如何为java自定义注释提供属性占位符支持

时间:2016-06-20 08:55:33

标签: java spring annotations aop

我创建了一个自定义Java注释并具有某些属性。如何支持字符串属性的属性占位符?

例如:

Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PublishEvent {

    public EventStore eventStore();
    public boolean isPersistent() default false;
    public String channelName();


}

我想用作:

@PublishEvent(channelName="${rabbit.event.default}")
public void someMethod(){}

其中 rabbit.event.default 是application.properties文件中定义的属性的键。我希望将属性键替换为值,就像@Value注释spring一样。

我使用Spring AOP拦截注释并进行处理。

2 个答案:

答案 0 :(得分:0)

由于我无法找到使用属性值丰富注释属性的内置方法,因此我最终创建了一个实现相同功能的实用程序类。

@Component
public class IntegrationUtils {

    @Autowired
    private Environment environment;

    @Resource
    private HashMap<String,String> propertyMapping;


    /**
     * Method to check if the text passed is a property and get the value
     * from the environment.
     *
     * @param text  : The text to be matched for the property
     * @return      : The property value if its starting with $ and has a matching value in
     *                environment
     *                Return the text itself is nothing matching
     */
    public String getEnvironmentProperty(String text) {

        // Check if the text is already been parsed
        if ( propertyMapping.containsKey(text)) {

            return propertyMapping.get(text);

        }


        // If the text does not start with $, then no need to do pattern
        if ( !text.startsWith("$") ) {

            // Add to the mapping with key and value as text
            propertyMapping.put(text,text);

            // If no match, then return the text as it is
            return text;

        }

        // Create the pattern
        Pattern pattern = Pattern.compile("\\Q${\\E(.+?)\\Q}\\E");

        // Create the matcher
        Matcher matcher = pattern.matcher(text);

        // If the matching is there, then add it to the map and return the value
        if( matcher.find() ) {

            // Store the value
            String key = matcher.group(1);

            // Get the value
            String value = environment.getProperty(key);

            // Store the value in the setting
            if ( value != null ) {

                // Store in the map
                propertyMapping.put(text,value);

                // return the value
                return value;

            }

        }

        // Add to the mapping with key and value as text
        propertyMapping.put(text,text);

        // If no match, then return the text as it is
        return text;

    }

}

答案 1 :(得分:0)

我使用org.springframework.util.StringValueResolver#resolveStringValue方法来解析placeholer值。可能是波纹管示例代码可以帮助您:

@Configuration
public class PublishEventConfiguration implements ApplicationContextAware, EmbeddedValueResolverAware {
  private ApplicationContext context;
  private StringValueResolver resolver;

  @Override
  public void setApplicationContext(ApplicationContext context) throws BeansException {
    this.context = context;
  }

   @Override
  public void setEmbeddedValueResolver(StringValueResolver resolver) {
    this.resolver = resolver;
  }


  @PostConstruct
  public void init() throws Exception {
    Collection<Object> publishEvents = context.getBeansWithAnnotation(PublishEvent.class).values();
    for (Object v : publishEvents) {
      PublishEvent cfg = v.getClass().getAnnotation(PublishEvent.class);
      String channelName = resolver.resolveStringValue(cfg.channelName());
    }
  }
}