Spring pointcut XML expression on custom annotation - spring

I have a custom annotation as follows:
#Inherited
#Target({ElementType.TYPE, ElementType.METHOD})
#Retention(RetentionPolicy.RUNTIME)
public #interface MyCustomAnnotation {
}
In Spring XML configuration I have the following:
<aop:pointcut id="fooPointcut" expression="#annotation(com.foo.blah.MyCustomAnnotation)"/>
This will only match on method annotations. How do I tweak the spel to also capture type/class annotations?

Use #within(com.foo.blah.MyCustomAnnotation) to
limit matching to join points within types that have the given annotation
A combined pointcut expression would become:
#annotation(com.foo.blah.MyCustomAnnotation) || #within(com.foo.blah.MyCustomAnnotation)
See Join Point Matching based on Annotations in the AspectJ 5 Developer's Notebook for further reference. Also note, that Spring's AOP doesn't support full AspectJ pointcuts, only a limited subset.
Also note that #annotation(com.foo.blah.MyCustomAnnotation) in AspectJ would match
all join points where the subject of the join point has the given annotation
meaning that it would match method-execution as well as method-call. In Spring AOP it only matches method-execution though, but it's better to write pointcut expressions that are valid in a broader scope as well, so don't forget to use an execution(...) pointcut too to restrict the pointcut.

Related

Custom Annotations in spring

In my project we have set up something like below
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD,ElementType.ANNOTATION_TYPE, ElementType.PARAMETER})
#Inherited
#Documented
#Qualifier(“MessageConverterQualifier”)
public #interface MessageConverterRef {}
Above Is used at many places in CoreConfig files (annotation based loading)
#Bean
#MessageConverterRef
public DocumentToABCResponseMessageConverter
documentToABCResponseMessageConverter() {
return new DocumentToABCResponseMessageConverter();
}
#Bean
#MessageConverterRef
public StringToABCResponseMessageConverter stringToABCResponseMessageConverter(
StringToDomBasedMessageConverter stringToDomBasedMessageConverter) {
return new StringToABCResponseMessageConverter(stringToDomBasedMessageConverter);
}
I am not able to understand what is the need of MessageConvertoerRef custom annotation here.
This custom annotation is used at now of places while initializing the beans using #Bean.
Request you to let me know what does it mean and what difference is it making .
This is an elegant solution to ensure compile-time safety for autowiring a set of beans by using the same qualifier. If you look at your custom annotation #MessageConverterRef you will see that the only truly meaningful annotation it is decorated with is:
#Qualifier(“MessageConverterQualifier”))
Use case: you happen to have a set of beans serving the same purpose (like having converters for different types, like you do) it would be really convinient to annotate all of them with the same Spring Qualifier (in your case MessageConverterQualifier), so that they can be all autowired into a list.
The next step is to recognize that having a set of beans scattered across your project that should be annotated with the same qualifier name is not enterily safe, neither the most elegant solution. Defining your own annotation (#MessageConverterRef) once, and reuse it everywhere it is needed reduces the chance of of error (typos) and at the same time increases readability and provides a cleaner code.
For more info on the topic I suggest reading the corresponding Spring doc, especially this part:
Qualifiers also apply to typed collections (as discussed above): e.g. to Set. In such a case, all matching beans according to the declared qualifiers are going to be injected as a collection. This implies that qualifiers do not have to be unique; they rather simply constitute filtering criteria. For example, there could be multiple MovieCatalog beans defined with the same qualifier value "action"; all of which would be injected into a Set annotated with #Qualifier("action").

Spring pointcut involving ignoring a class

I have a point cut for all classes in Spring AOP like
#Pointcut("execution(* com.company.app..*(..))")
Now I need to exclude a class say com.company.app.IgnoreClass.
Can someone please help me write the pointcut?
The Pointcut to exclude all methods in IgnoreClass would be:
#Pointcut("execution(* com.company.app..*(..)) && !execution(* com.company.app.IgnoreClass.*(..)) ")
Documentation about pointcuts expression here, also more related information on Spring AOP declaring pointcuts here.

while the pointcut be apply to bean ctor and all get/set property methods?

I have a Spring AOP pointcut execution(* someService.*(..)).
Will this pointcut match constructor and bean get/set property methods?
THIS is not my intention, and also maybe this behaviour will hurt performance.
I just want to advise REAL service methods, such us getUserByID etc.
How do I exclude those methods (get/set/constructor)?
That pointcut will match public methods in Spring AOP. So getters and setters, but not constructors.
The Spring reference for this is here. Section 8.2.3, look for "even constructors".
A clean way to only reference a group of methods is to apply the pointcut to an interface implemented by your service, instead of the service itself. This assumes your interface only contains business methods you want to advise.
in case it's a third party library and you don't want to use a marker interface for some reason, you can always base yourself on naming conventions of the methods. For example this applies the aspect to getters only:
execution(* someService.get*(..))
this expression applies the aspect to both getters and setters:
execution(* someService.get*(..)) && execution(* someService.set*(..))

Is the following pointcut valid?

I came across the following Spring AOP pointcut in a tutorial:
execution(public * * (..))
it was said that it would cause the execution of all public methods. Is that correct? AFAIK we can only intercept public methods, and that public keyword there is even illegal.
In addition to #Mario's answer, the spring docs on AOP say the following (emphasis mine):
Note Due to the proxy-based nature of Spring's AOP framework,
protected methods are by definition not intercepted, neither for JDK
proxies (where this isn't applicable) nor for CGLIB proxies (where
this is technically possible but not recommendable for AOP purposes).
As a consequence, any given pointcut will be matched against public
methods only!
If your interception needs include protected/private methods or even
constructors, consider the use of Spring-driven native AspectJ weaving
instead of Spring's proxy-based AOP framework. This constitutes a
different mode of AOP usage with different characteristics, so be sure
to make yourself familiar with weaving first before making a decision.
In addition, the pointcut grammer is as follows:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?
name-pattern(param-pattern) throws-pattern?)
Wherby the modifier-pattern would be public,protected etc but is optional...
Yes, it seems to be a valid pointcut, and it does exactly what he says.
In addition, it is worth to note that replacing the "public" keyword with "protected" is perfectly legal and it still works! Strangely it works also with "private" methods...
(Tested with Spring 3.1.2 + AspectJ 1.6.9)
As far as I know, CGLib proxies can be used to proxy protected methods, however they are effective only if they are invoked from a different object instance. So technically, it should be possible to advice protected methods exactly in the same way as public ones.
(As reported by #beny23 advicing protected/private methods does not work with Spring AOP proxy implementation, but only with Spring driven AspectJ weaving)
pointcut: designator(modifier returnType package.type.method(params))
in your case
execution(public * * (..))
would execute for all public methods with ANY return type in the project dir with 0 to many parameters

Aspect pointcut to match Annotation property

I'm trying to use Spring AOP with AspectJ support to weave methods with a certain annotation. I know it's easy to do so by using a pointcut #annotation(classname)
But I need to create weavers based on properties of the annotation. The annotation in question is Spring's #RequestMapping, and I need to check the method property of it.
I know I could access it inside the body of the advice, but what I really would like is to create one advice per matched annotation.
Is this possible?
There doesn't seem to be a way to do it, but you can check the parameters of the annotation immediately on entry and immediately pass it on if they're not satisfied.
#Around("execution(public * *(..)) && #annotation(reqMap)")
public Object myMethod(ProceedingJoinPoint pjp, RequestMapping reqMap)
throws Throwable {
if (notRightPropertyValue(reqMap))
return pjp.proceed();
// Do your stuff here
}
If this is too inelegant, consider inventing an extra annotation to mark just the methods that you're really interested in.

Resources