您的位置:首页 > 编程语言 > Java开发

Spring中BeanPostProcessors【2】优雅实现业务分离

2017-01-24 10:02 501 查看
1 概述
BeanPostProcessors可以在spring IoC容器初始化受管Bean前、属性设置后对该Bean先做一些预处理,或者在容器销毁受管Bean之前自己释放资源。《Spring中BeanPostProcessors【1】简单预处理》一文有实例说明。本文介绍一个具体案例,优雅实现业务分离。

2 基础类
设想一个系统中分很多模块,对于模块又有不同的操作命令,对于不同模块的不同命令场景,会有不同的处理。当然通过if else判断可以实现,但可读性和优雅性太差。下面采取注解+BeanPostProcessors的方式优雅实现。

【1】注解类

package com.xy.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Module {

/**
* 模块号
*/
short moduleId();
}

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BizCommand {

/**
* 命令号
*/
short cmdId();
}

【2】常量类

package com.xy.constants;
public interface ConstantCmd {

// 添加
public short ADD = 1;

// 删除
public short DELETE = 2;
}

public interface ConstantModule {

// 学生模块
public short STUDENT = 1;

// 教师模块
public short TEACHER = 2;
}

【3】业务类

package com.xy.service;
import com.xy.annotation.BizCommand;
import com.xy.annotation.Module;
import com.xy.constants.ConstantCmd;
import com.xy.constants.ConstantModule;

@Module(moduleId = ConstantModule.STUDENT)
public interface StuService {

@BizCommand(cmdId = ConstantCmd.ADD)
public void add(String name);

@BizCommand(cmdId = ConstantCmd.DELETE)
public void delete(String name);
}

import org.springframework.stereotype.Component;

@Component // 该类需要被Spring托管
public class StuServiceImpl implements StuService {

public void add(String name) {
System.out.println("I am student add method.add name:" + name);
}

public void delete(String name) {
System.out.println("I am student delete method.delete name:" + name);
}

}


3 核心类

总体思路是利用模块号+命令号对应不同的方法和实现类,方法和实现类被存在对应列表中。

传入模块号和命令号,即可获取对应的方法名和实现类,执行即可。

package com.xy.scanner;

import java.lang.reflect.Method;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
import com.xy.annotation.BizCommand;
import com.xy.annotation.Module;

@Component // 该类也需要被Spring托管
public class BizScanner implements BeanPostProcessor {

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

// 容器管理的类信息(stuServiceImpl)
Class<? extends Object> clazz = bean.getClass();

// 该类实现的接口(stuService)
Class<?>[] interfaces = clazz.getInterfaces();

if (null != interfaces && interfaces.length > 0) {
for (Class<?> interFace : interfaces) {

// 获取接口注解
// 模块信息
Module module = interFace.getAnnotation(Module.class);
if (null == module)
continue;

// 该接口所有方法
Method[] methods = interFace.getMethods();
if (null != methods && methods.length > 0) {
for (Method method : methods) {
// 命令信息
BizCommand bizCommand = method.getAnnotation(BizCommand.class);
if (null == bizCommand)
continue;

// 模块号
short moduleId = module.moduleId();
// 命令号
short cmdId = bizCommand.cmdId();
if (BizInvokerManager.getInvoker(moduleId, cmdId) == null) {
BizInvokerManager.addInvoker(moduleId, cmdId, BizInvoker.valueOf(method, bean));
} else {
System.out.println("重复命令:" + "module:" + moduleId + " " + "cmdId:" + cmdId);
}
}
}
}
}
return bean;
}
}

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
* 命令执行器
*/
public class BizInvoker {

/**
* 方法
*/
private Method method;

/**
* 目标对象(实现类)
*/
private Object target;

/**
* 封装执行器
*
* @param method 方法 com.xy.service.StuService.add
* @param target 目标 com.xy.service.StuServiceImpl@273e07bd
* @return 执行器
*/
public static BizInvoker valueOf(Method method, Object target) {
BizInvoker invoker = new BizInvoker();
invoker.setMethod(method);
invoker.setTarget(target);
return invoker;
}

/**
* 调用方法
*
* @param paramValues 参数
* @return 执行结果
*/
public Object invoke(Object... paramValues) {
try {
// method 方法 com.xy.service.StuService.add
// target 目标 com.xy.service.StuServiceImpl@273e07bd
return method.invoke(target, paramValues);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}

public Method getMethod() {
return method;
}

public void setMethod(Method method) {
this.method = method;
}

public Object getTarget() {
return target;
}

public void setTarget(Object target) {
this.target = target;
}
}

import java.util.HashMap;
import java.util.Map;

/**
* 命令执行器管理者
*/
public class BizInvokerManager {

/**
* 命令调用器(第1个short是模块号,第2个short是命令号)
*/
private static Map<Short, Map<Short, BizInvoker>> invokers = new HashMap<Short, Map<Short, BizInvoker>>();

/**
* 添加命令调用
*
* @param module 模块号
* @param cmd 命令号
* @param invoker 调用器
*/
public static void addInvoker(short moduleId, short cmdId, BizInvoker invoker) {
Map<Short, BizInvoker> map = invokers.get(moduleId);
if (null == map) {
map = new HashMap<Short, BizInvoker>();
invokers.put(moduleId, map);
}
map.put(cmdId, invoker); // 改变引用,将命令号存入
}

/**
* 获取命令调用
*
* @param module 模块号
* @param cmd 命令号
*/
public static BizInvoker getInvoker(short moduleId, short cmdId) {
Map<Short, BizInvoker> map = invokers.get(moduleId);
if (map != null) {
return map.get(cmdId);
}
return null;
}

}


4 Spring文件


<context:component-scan base-package="com.xy.scanner" />
<context:component-scan base-package="com.xy.service" />


5 测试

package com.xy.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.xy.constants.ConstantCmd;
import com.xy.constants.ConstantModule;
import com.xy.scanner.BizInvoker;
import com.xy.scanner.BizInvokerManager;

public class TestBean {

public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println(ac);

BizInvoker invoker1 = BizInvokerManager.getInvoker(ConstantModule.STUDENT, ConstantCmd.ADD);
invoker1.invoke("xy1");

System.out.println("========================");

BizInvoker invoker2 = BizInvokerManager.getInvoker(ConstantModule.STUDENT, ConstantCmd.DELETE);
invoker2.invoke("xy2");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: