【问题标题】:How can I find all beans with custom annotation and inject it to Map of bean-manager?如何找到所有带有自定义注释的 bean 并将其注入到 bean-manager 的 Map 中?
【发布时间】:2019-03-17 10:37:50
【问题描述】:

我有一些这样的豆子:

@MyAnnotation(type = TYPE1)
@Component
public class First implements Handler {

@MyAnnotation(type = TYPE2)
@Component
public class Second implements Handler {

@MyAnnotation(type = TYPE3)
@Component
public class Third implements Handler {

我有这个 bean 的控制 bean:

@Component
public class BeanManager {

    private Map<Type, Handler> handlers = new HashMap<>();

    @Override
    public Handler getHandler(Type type) {
        Handler handler = map.get(type);
        if (handler == null)
            throw new IllegalArgumentException("Invalid handler type: " + type);
        return handler ;
    }
}

如何在启动服务器时将handlers map填入BeanManager

我知道 3 种方法:

1) 在构造函数中填充地图:

public BeanManager(First first, Second second, Third third){
  handlers.put(Type.TYPE1, first);
  handlers.put(Type.TYPE2, second);
  handlers.put(Type.TYPE3, third);
 }

我不需要注释,但是这种方法很糟糕,我带来了它来完成图片。

2) post costroctor(@PostConstruct)中填图:

    @PostConstruct
    public void init(){
       Map<String, Object> beansWithAnnotation = context.getBeansWithAnnotation(MyAnnotation.class);
       //get type from annotation
       ...
      //add to map
      handlers.put(type, bean);
     }

在此解决方案中,BeanManager 包含 context当我将在我的代码中使用 BeanManager 时,它将拉取上下文。我不喜欢这种方法。

3) 将 bins 中的注解搜索移动到 BeanPostProcessor 并将 setter 添加到 BeanManager

@Component
public class MyAnnotationBeanPostProcessor implements BeanPostProcessor {

    private final BeanManager beanManager;

    public HandlerInAnnotationBeanPostProcessor(BeanManager beanManager) {
        this.beanManager = beanManager;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        Annotation[] annotations = bean.getClass().getAnnotations();
        for (Annotation annotation : annotations) {
            if (annotation instanceof MyAnnotation) {
                Type[] types = ((MyAnnotation) annotation).type();
                for (Type type: types) {
                    beanManager.setHandler(type, (Handler) bean);
                }
            }
        }
        return bean;
    }
}

但是在这个解决方案中我不喜欢setHandler 方法

【问题讨论】:

    标签: java spring spring-boot dependency-injection


    【解决方案1】:

    让我们稍微改变一下方法

    @Component
    public class BeanManager {
    
        private Map<Type, Handler> handlers = new HashMap<>();
    
        //haven't tested, just an idea : )
        @Autowired
        public void setHandler(List<Handler> handlersList) {
            for(Handler handler : handlers) {
                Type type = handler.getClass().getAnnotation(MyAnnotation.class).type();
                handlers.put(type, handler);
            }
        }
    }
    

    如果您需要更多灵感,请查看LINK

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 2012-04-26
      • 1970-01-01
      相关资源
      最近更新 更多