背景
设计了一套日志框架,希望通过注解指定时可以获取全局配置的信息,然后做一些对应的处理。
代码实现
获取类注解
@EnableAutoLog
注解是放在类上的,可以通过 applicationContext.getBeansWithAnnotation(EnableAutoLog.class)
获取,然后处理。
这里使用 @PostConstruct
做了一点优化,让这种查找只做一次,避免性能消耗。
@Aspect
@Component
@EnableAspectJAutoProxy
public class AutoLogAop {
@Autowired
private ApplicationContext applicationContext;
/**
* 日志输出的实现类
* @since 0.0.9
*/
private Class<? extends IAutoLog>[] autoLogs;
/**
* 初始化实现类
* @since 0.0.9
*/
@PostConstruct
public void initAutoLogs() {
//获取自定义注解的配置的所有bean
final Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(EnableAutoLog.class);
for (Object bean : beansWithAnnotation.values()) {
final EnableAutoLog annotation = AnnotationUtils.findAnnotation(bean.getClass(), EnableAutoLog.class);
this.autoLogs = annotation.value();
}
}
}
获取方法上的信息
public static void handleRegisterBeanWithSpringToInitConfigurerationBean(ApplicationContext applicationContext) {
//获取自定义注解的配置
final Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(InitRetryRabbitMq.class);
for (String key : beansWithAnnotation.keySet()) {
//Spring 代理类导致Method无法获取,这里使用AopUtils.getTargetClass()方法
Method[] methods = ReflectionUtils.getAllDeclaredMethods(AopUtils.getTargetClass(beansWithAnnotation.get(key).getClass()));
for (Method method : methods) {
//获取指定方法上的注解的属性
final InitRetryRabbitMq initRetryRabbitMq = AnnotationUtils.findAnnotation(method, InitRetryRabbitMq.class);
if (null != initRetryRabbitMq) {
//验证必要的注解的属性
String queueName = Optional.ofNullable(initRetryRabbitMq.queueName()).orElseThrow(() -> new IllegalArgumentException("Please specify the queue name of the queue!"));
//多个bean的时候相当于起个别名
String registerBean = queueName + "InitConfigurerationBean";
//将bean注册到Spring容器中,通过构造函数的方式进行注入
SpringRegisterBean.registerBean((ConfigurableApplicationContext) applicationContext, registerBean, InitConfigurerationBean.class, initRetryRabbitMq, applicationContext);
log.info("The registration bean is " + registerBean + ",Configuration information is " + JSONObject.toJSONString(initRetryRabbitMq));
}
}
}
}
这个例子还是先指定了 beans,我们可以先获取所有的 beans,然后处理。