如何找到所有带有自定义注释的bean并将其注入到bean-manager的Map中?

时间:2018-10-12 08:32:35

标签: java spring spring-boot dependency-injection

我有一些像这样的豆子:

@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 {

我有这个豆的控制豆:

@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)移动将对箱中注释的搜索移动到BeanPostProcessor并将设置器添加到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方法

1 个答案:

答案 0 :(得分:0)

让我们稍微改变一下

@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