Reputation: 517
I have created a custom Java annotation and has certain attributes. How can I support the property placeholder for string attributes ?
Eg:
Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PublishEvent {
public EventStore eventStore();
public boolean isPersistent() default false;
public String channelName();
}
I want to use as :
@PublishEvent(channelName="${rabbit.event.default}")
public void someMethod(){}
where rabbit.event.default is a key for a property defined in application.properties file. I want to have the property key replaced with value as in the case of @Value annotations of spring.
I am using Spring AOP to intercept the annotation and do processing.
Upvotes: 2
Views: 3322
Reputation: 1913
I Use org.springframework.util.StringValueResolver#resolveStringValue
method to resolve the placeholer value. May be the bellow sample code can help you:
@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());
}
}
}
Upvotes: 2
Reputation: 517
As I was not able to find a built-in method for enriching the annotation attributes with property value, I ended up creating a utility class that does the same.
@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;
}
}
Upvotes: 0