1、假设我自定义注解 NameSpace
@Target(ElementType.METHOD) //指定注解的使用范围为 方法
@Retention(RetentionPolicy.RUNTIME) //运行时生效
public @interface NameSpace {
/**
* Name Space
*
* @return value
*/
String value();
}
2、在启动时继承 BeanPostProcessor,初始化Bean时会先调用这个接口的实现方法。 其中有postProcessAfterInitialization前置方法与postProcessBeforeInitialization后置方法,前置方法我们一般不去使用,我们在后置方法中,去解析这个注解,然后加上该有的功能
public class NameSpaceSpringAnnotationScanner implements BeanPostProcessor {
private final List<Class<? extends Annotation>> annotations =
Arrays.asList(OnConnect.class, OnDisconnect.class, OnEvent.class);
@Autowired
private SocketIOServer socketIOServer;
@Autowired
@Qualifier("evcs")
private SocketIOServer evcsSocketIOServer;
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
//反射获取这个Bean的对应类的Class元信息
Class<?> targetClass = **AopUtils.getTargetClass(bean);**
//为对应的注解加上对应的功能
// 注意加final,lambada闭包 不能访问非final的局部变量
final AtomicBoolean add = new AtomicBoolean(true);
ReflectionUtils.doWithMethods(targetClass,
method -> {
// 方法存在这三个注解,就可以添加到名字空间中
// 假设存在 nameSpace注解 则添加 到对应的value对应的空间
// 不存在则 默认的空间
boolean b = annotations.stream().anyMatch(annotationClass -> method.isAnnotationPresent(annotationClass));
if (b) {
if (method.isAnnotationPresent(NameSpace.class)) {
evcsSocketIOServer.addListeners(bean, bean.getClass());
} else {
socketIOServer.addListeners(bean, bean.getClass());
}
log.info("add listener:【{}】 into name space ", beanName);
}
add.set(false);
}, method -> add.get());
return bean;
}
//前置bean不加上任何的功能,直接返回
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}