spring初始化后获取自定义注解bean

目的是通过注解将特定类的信息(如接口编号)与类关联,之后可通过接口编号获取对应bean来执行对应逻辑。

1.新建注解类:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Service
public @interface ServiceCode {
    String code() default "";

    String className() default "";
}

包含接口编号和beanName信息。

2.新建接口类:

@ServiceCode(code = "100010", className = "echoService")
@Service("echoService")
public class EchoService {

}

3.实现接口ApplicationListener来监听spring容器初始化完成后执行:

@Component
@Order(1)
public class ServiceInitListener implements ApplicationListener {
    private static final Logger LOGGER = LoggerFactory.getLogger(ServiceInitListener.class);

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        ApplicationContext applicationContext = event.getApplicationContext();
        //注意 需要时根容器才能通过注解获取到bean,比如event直接获取的容器中只有一些公共注册bean
        if (applicationContext.getParent() != null) {
            applicationContext = applicationContext.getParent();
        }
        Map beansWithAnnotation = applicationContext.getBeansWithAnnotation(ServiceCode.class);
        for (Object bean : beansWithAnnotation.values()) {
            ServiceCode annotation = bean.getClass().getAnnotation(ServiceCode.class);
            String code = annotation.code();
            String className = annotation.className();
            //注册接口编号和beanName
            //在统一入口可通过code获取beanName,然后通过springContext获取对应bean执行自定义逻辑
            //或者完成其他逻辑
        }
    }

}

注意:
 ContextRefreshedEvent获取到的上下文环境不是根spring容器,其中只有部分spring内置bean,无法通过注解获取到自定义bean,需要获取其父容器来完成操作。我第一次获取是beanList总为空,后来发现其容器内部bean没有自定义的service bean,获取父容器后操作一切正常。

通过@Order注解来定制执行顺序,越小越优先执行。

你可能感兴趣的:(spring,spring,java)