限制Spring应用程序的自定义注释

时间:2013-06-20 13:32:27

标签: spring

我想创建一个自定义弹簧注释,它可以在某些条件或参数下工作。但作为业务约束,我需要与我的所有应用程序共享具有Genre注释的库。是否可以配置我的注释以限制我的一些应用程序,如@Profile注释?

@Target({ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Genre {
  String value();
}

及其用法

public class MovieRecommender {
@Autowired

   @Genre("Action")
   private MovieCatalog actionCatalog; 

   private MovieCatalog comedyCatalog;

   @Autowired
   public void setComedyCatalog(@Genre("Comedy") MovieCatalog comedyCatalog) { 
      this.comedyCatalog = comedyCatalog;
   }
// ...
}

1 个答案:

答案 0 :(得分:0)

我认为不可能改变@Autowired注释的行为。

但是,您可以轻松实现自己的BeanPostProcessor并使用所有方便的Spring类,例如AnnotationUtilsReflectionUtils等。

在一个项目中,我们需要自定义JAX-WS端口注入。所以我们创建了@InjectedPort注释并实现了我们自己的InjectedPortAnnotationBeanPostProcessor(这只是说明了自定义注入逻辑的简单性,代码本身的目的与问题无关):

@Override
public Object postProcessBeforeInitialization(final Object bean,  String beanName) {
    // Walk through class fields and check InjectedPort annotation presence
    ReflectionUtils.doWithFields(bean.getClass(), new FieldCallback() {
        @Override
        public void doWith(final Field field) {
            // Find InjectedPort annotation
            final InjectedPort injectedPort = field.getAnnotation(InjectedPort.class);
            if (injectedPort == null) {
                return; // Annotation is not present
            }
            // Get web service class from the annotation parameter
            Class<?> serviceClass = injectedPort.value();
            // Find web service annotation on the specified class
            WebServiceClient serviceAnnotation = AnnotationUtils.findAnnotation(serviceClass, WebServiceClient.class);
            if (serviceAnnotation == null) {
                throw new IllegalStateException("Missing WebService " + "annotation on '" + serviceClass + "'.");
            }
            // Get web service instance from the bean factory
            Service service = (Service) beanFactory.getBean(serviceClass);
            // Determine the name of the JAX-WS port
            QName portName = new QName(service.getServiceName().getNamespaceURI(), findPortLocalName(serviceClass, field.getType()));
            // Obtain the JAX-WS port
            Object port = service.getPort(portName, field.getType());
            // Inject the port into the target bean
            ReflectionUtils.makeAccessible(field);
            ReflectionUtils.setField(field, bean, port);
        }
    });
    return bean;
}