--------------------------------------------------------------------
# netty-common
首先定义2个注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Cmd {
String cmd();
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Module {
String module();
}
构造Invoker实体和InvokerTable。NettyProcessBeanScanner在bean初始化后扫描所有注解 ,创建对应的Invoker, 并把他们加入到InvokerTable中
package com.bfxy.scanner;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import lombok.Data;
@Data
public class Invoker {
private Method method;
private Object target;
/**
* $createInvoker
* 创建invoker对象
* @param method
* @param target
* @return
*/
public static Invoker createInvoker(Method method, Object target) {
Invoker invoker = new Invoker();
invoker.setMethod(method);
invoker.setTarget(target);
return invoker;
}
/**
* $invoke 反射调用
* @param params
* @return 返回方法的执行结果
*/
public Object invoke(Object... params) {
try {
return method.invoke(target, params);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
public class InvokerTable {
private static ConcurrentHashMap<String /*module */, Map<String /*cmd*/, Invoker>> invokerTable =
new ConcurrentHashMap<String /*module */, Map<String /*cmd*/, Invoker>>();
/**
* $addInvoker
* @param module
* @param cmd
* @param invoker
*/
public static void addInvoker(String module, String cmd, Invoker invoker) {
Map<String /*cmd*/, Invoker> map = invokerTable.get(module);
if(map == null) {
map = new HashMap<String /*cmd*/, Invoker>();
invokerTable.put(module, map);
}
map.put(cmd, invoker);
}
/**
* $getInvoker
* @param module
* @param cmd
* @return
*/
public static Invoker getInvoker(String module, String cmd) {
Map<String /*cmd*/, Invoker> map = invokerTable.get(module);
if(map != null) {
return map.get(cmd);
}
return null;
}
}
package com.bfxy.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.bfxy.annotation.Cmd;
import com.bfxy.annotation.Module;
/**
* $NettyProcessBeanScanner
* 使用BeanPostProcessor 在bean初始化之后加载所有的bean
* 然后找到带有@Module 的bean对象
* 接下来进行扫描bean对象下的方法中带有 @Cmd, 注解的方法
* 最后创建对应的Invoker, 并把他们加入到InvokerTable中
*/
@Component
public class NettyProcessBeanScanner implements BeanPostProcessor {
//BeanPostProcessor,针对所有Spring上下文中所有的bean,可以在配置文档applicationContext.xml中配置一个BeanPostProcessor,然后对所有的bean进行一个初始化之前和之后的代理。
// BeanPostProcessor接口中有两个方法:
// postProcessBeforeInitialization方法在bean初始化之前执行,
// postProcessAfterInitialization方法在bean初始化之后执行。
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 1.首先获取当前bean的class类型
Class<?> clazz = bean.getClass();
boolean isPresent = clazz.isAnnotationPresent(Module.class);//是否有Module注解
if(isPresent) {
Method[] methods = clazz.getMethods();
if(methods != null && methods.length > 0) {
for(Method m : methods) {