How to configure the pointcut expressions dynamically - spring

I am looking for a solution for the problem where I can configure the pointcut expressions dynamically by reading from a properties file or database.
for example:
#Around("execution(* com.example.updateUser(..))")
in above example, we have hardcoded the expression.
I am looking for the solution where I can read
execution(* com.example.updateUser(..))
and then use it in #Around annotation.
I did not come across similar problem on web.
Any solution for such problem is highly appreciated.
Thank you!!

You can use schema-based AOP and define the pointcut in classical, old-school XML style. Spring XML config is a text file being read while starting up the application and thus would satisfy your requirement.
If you like to manually wire your pointcut into an aspect, you can do that, too. Whether you define a string variable or field containing the pointcut directly in your application or read the pointcut from a text file, is completely up to you. Search for the terms DefaultPointcutAdvisor and AspectJExpressionPointcut in my answer here, somewhere inside the "update 2" and "update 3" parapgraphs. There you will also find a link to a complete sample project.

Related

How to write a advice which will inject for all the DAO classes which is annotated with #Repository

When I tried to find the answer for "difference between #component,#service,#Repository,#controller" I found one additional answer "It will help in case of AOP when you separate the layers by using these annotation.
For example if you want to inject one Aspect of logging (before,after)to all the DAO,you are able to do that using AOP as you have three distinct Layers and are not mixed.
Can anyone please suggest me the sample code how to write join points which will apply to all #Repository by using this annotation.I know how to create joint points with the help of expressions,autoproxycreater(which will tell inject advice whose method matches the advisor's pointcut) but how we will tell to inject advice to all the classes which is annotated with #Repository.
The following pointcut expression to advice based on annotation #target(org.springframework.stereotype.Repository) should help.

Reusing Spring RequestMapping parsing functionality

I have some properties like
/my/{custom}/url
I would need to replace {custom} with some value at runtime
I know that Spring is using "#RequestMapping" with a similar syntax for #PathAttribute matching.
I'm wondering if there is some Class I can reuse from Spring to achieve what I need.
A good option for this is to use a UriComponentsBuilder - see reference here: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/util/UriComponentsBuilder.html
UriComponentsBuilder.fromPath("/test/{one}/{two}").buildAndExpand(map).toUriString()

Spring SpEL Wiring Collection

I was reading Spring in action these days and came across the following code. I'm wondering if the following code can actually work.
<property name="chosenCity" value="#{cities[T(java.lang.Math).random() * cities.size()]}"/>
It seems like
T(java.lang.Math).random() * cities.size()
will return a double value. How can we reference a double value index in a array? The author didn't explain this? I was wondering if Spring SpEL has any auto-converting mechanism to trim a double value to int?
Thanks!
Yes, SpEL will provide necessary conversions (if it can). See section 7.3.1 in the Spring Reference Manual.

Custom annotation like #Value

I need to create a means to add a custom annotation like
#Value("${my.property}")
However, in my case I need to get the value from a database rather then a properties file.
Basically I would like to create a bean on container startup that reads in property name value pairs from a database and can then inject these into fields belonging to other beans.
Approach #1:
One way is to create an Aspect, with a point-cut expression that matches any method having this annotation.
Your aspect will then:
Read the property value in the annotation
Look up the required value an inject it into the class.
AOP Kickstart
Here's a guide to getting started with AOP in Spring
http://www.tutorialspoint.com/spring/aop_with_spring.htm
Joinpoint matching
Here's a reference that describes how to create a join-point that matches on annotations: http://eclipse.org/aspectj/doc/next/adk15notebook/annotations-pointcuts-and-advice.html
Approach #2:
Another way is to use a BeanFactoryPostProcessor - this is essentially how a PropertyPlaceholderConfigurer works.
It will look at your bean definitions, and fetch the underlying class.
It will then check for the annotation in the class, using reflection.
It will update the bean definition to include injecting the property as per the value in the annotation.
. . actually I think approach #2 sounds more like what you want - all of the processing happens on "start-up". . . (In actual fact your modifying the bean recipes even before startup). . whereas if you used AOP, you'd be intercepting method invocations, which might be too late for you?
Namespace Handler
If you wanted you could even create your own Spring namespace handler to turn on your post processor in a terse way. Eg:
<myApp:injectFromDb />
as an alternative to:
<bean class="MyDatabaseLookupProcessorImpl etc, etc. />
Update: Approach #3
As of Spring 3.1 there's also the PropertySourcesPlaceholderConfigurer, that will provide most of the plumbing for you, so you can achieve this with less code.
Alternatively you should be able to configure kind of properties repository bean and then use it in SpEL directly in #Value annotation.
Let's say you'd have bean called propertiesRepository in your context that implements following interface:
interface PropertiesRepository {
String getProperty(String propertyName);
}
then on bean where you want to inject values you can use following expression
#Value("#{propertiesRepository.getProperty('my.property')}")
String myProperty;
You can use #Value annotation by injecting database configuration in application environment itself.
I know this is an old question but I didn't find an exact solution. So documenting it here.
I have already answered the same on different forum.
Please refer to this answer for exact solution to your problem.

Spring 3 Field Formatting

I am looking at using the Spring's Field formatting in particular the existing DateFormatter. I do understand that I need to specify a pattern on an annotation in my POJO.
Instead of hard coding the pattern I need to be able to provide it dynamically, I know this is not feasible with annotations. To properly support internationalization I would need to look up a pattern from a properties file before passing it to a Formatter.
Can anyone suggest an approach I can take?
Not sure however you may try implementing InitializingBean or init-method and set the values dynamically.
like suggested in spring forum for cron expression.

Resources