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<ContextRefreshedEvent> {
    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<String, Object> 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註解來定製執行順序,越小越優先執行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章