Spring AOP superclass method execution without #target - spring

Consider the following situation:
class A() {
void a();
}
#MyAnnotation
class B extends A {
void b();
}
I want to advice all methods of all classes annotated with #MyAnnotation (i.e B.a()).
That's pretty easy task due to the possibility of using #target pointcut expression.
BUT! in that case all beans in a container (even unsuitable) will be Proxified what is unacceptable.
Now the question: Is it possible to build up pointcut expressino without #target but with the same effect?

You can use within like this.
execution(* *(..)) && within(#MyAnnotation *)
refer to https://stackoverflow.com/a/2522821/672586 and http://forum.springsource.org/showthread.php?28525-Difference-between-target-and-within-in-Spring-AOP for more details. The relevant section from the forum post explaining the difference between within and target
One difference between the two is that #within() is matched statically, requiring the corresponding annotation type to have only the CLASS retention. Whereas, #target() is matched at runtime, requiring the same to have the RUNTIME retention. Other than that, within the context of Spring, there is no difference between the join points selected by two.

Related

spring annotation advice order on method level

I have created 2 custom spring #annotations. I need to define the order of these annotations, on method-level, not on class-level. Does #order, work on the method level, too?
#Aspect
#Component
public class ABC {
private ThreadLocal<logDTO> myThreadLocal;
#Before("#annotation(CommunicationLogInit)")
public void CampaignLogsInit(){
myThreadLocal = new ThreadLocal<logDTO>();
myThreadLocal.set(new logDTO());
}
#Around("#annotation(CommunicationAudit)")
public Object generateLog(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
Method method = signature.getMethod();
int counter = 0;
for(Parameter parameter : method.getParameters()){
Annotation eventName = parameter.getAnnotation(EventName.class);
Annotation rtnInfo = parameter.getAnnotation(RtnInfo.class);
if(eventName!=null){
System.out.println(joinPoint.getArgs()[counter]);
myThreadLocal.get().setName("ABC");
}
}
}
}
The Spring AOP manual answers your question in section advice ordering:
Advice Ordering
What happens when multiple pieces of advice all want to run at the same join point? Spring AOP follows the same precedence rules as AspectJ to determine the order of advice execution. The highest precedence advice runs first “on the way in” (so, given two pieces of before advice, the one with highest precedence runs first). “On the way out” from a join point, the highest precedence advice runs last (so, given two pieces of after advice, the one with the highest precedence will run second).
When two pieces of advice defined in different aspects both need to run at the same join point, unless you specify otherwise, the order of execution is undefined. You can control the order of execution by specifying precedence. This is done in the normal Spring way by either implementing the org.springframework.core.Ordered interface in the aspect class or annotating it with the Order annotation. Given two aspects, the aspect returning the lower value from Ordered.getValue() (or the annotation value) has the higher precedence.
When two pieces of advice defined in the same aspect both need to run at the same join point, the ordering is undefined (since there is no way to retrieve the declaration order through reflection for javac-compiled classes). Consider collapsing such advice methods into one advice method per join point in each aspect class or refactor the pieces of advice into separate aspect classes that you can order at the aspect level.
I think the last paragraph is of particular interest to you.

AspectJ pointcut on method in Spring CrudRepository

I'm using Spring's CrudRepository in combination with the annotation #RepositoryRestResource to implement a simple CRUD-app that can be used throught a RESTful API. I now want to add an AspectJ pointcut on my repository, so that some functionalities will be executed whenever a CRUD-method from the interface is called.
First, I extend Spring's CrudRepository to add some custom functionalities in my own interface:
#RepositoryRestResource(collectionResourceRel = "customers", path = "customers")
public interface CustomerRestRepository extends CrudRepository<Customer, Integer>{
Customer findOneByGuid(#Param("customerGuid") String customerGuid);
//Other custom methods.
}
Everything is working fine and I'm able to call this method via my REST client. I do not have to implement the interface CustomerRestRepository since Spring is doing the job as a miracle in behind. This is one of the crucial advantages of extending Springs's CrudRepository.
The problem, I'm facing now, is to add an AspectJ pointcut on this custom method findOneByGuid() that will, for example, log every call of the method after it's execution.
What I've tried by so far is:
#Aspect
public aspect AfterCustomerCrudAspect {
#Pointcut(
"execution(* com.x.y.z.CustomerRestRepository.findOneByGuid(..))")
public void customerCrudMethod() {}
#AfterReturning("customerCrudMethod()")
public void doSomething() {
//Do something
}
}
I've also tried:
1) execution(* com.x.y.z.CustomerRestRepository+.findOneByGuid(..))
2) execution(* org.springframework.data.repository.Repository+.*(..))
3) within(com.x.y.z.CustomerRestRepository)
4) annotation(RepositoryRestResource)
...and many others I do not remember. All with the same frustrating result: The advice is never applied.
By the way, I do not face any exceptions and if I try execution(* *.*(..)), the advice is working well - but, of course, not limited to the method findOneByGuid(). Thus, I think my code is correct in general.
I know that it is not possible to set pointcuts on interfaces. But since I do not have to implement the interface CustomerRestRepository by my own to get things working, I need to find a way to set a pointcut on an interface's method - or to find some other solution.
Well, one possible solution to that would be to implement the interface CustomerRestRepository. But then I've to do all the implementation work for the repository by my own and skip using the advantages of Spring's CrudRepository.
Thus, my question is, if there is a possibility to set a AspectJ pointcut on methods in a Spring CrudRepository.
Many thanks in advance for all the answers.
Well, I solved my problem in a different way.
Sometimes, things are less complicated than expected. Adding an AspectJ pointcut on a Spring CRUD-repository to execute some functionalities, whenever an entity is changed was not the best idea. (And at the best of my knowledge, it is not possible at all.)
There is a much more easier way to implement my requirement: The package javax.persistence provides the annotation #EntityListeners that suites perfectly to this job. So, annotate the entity class with the listener and implement the needed functionalities within the listener class:
#Entity
#EntityListeners(CustomerEntityListener.class)
//#Table, #NamedQueries and other stuff ...
public class Customer implements Serializable {
...
}
Implementation of the EntityListener:
public class CustomerEntityListener {
#PostPersist
public void customerPostPersist(Customer customer) {
//Add functionalities
}
}
The EntityListeneralso provides annotation for #PostUpdate, #PostRemove and so on - visit this site for more information.

static pointcut evaluation when it is done

Spring AOP weaving process is done at runtime when the request to that specific method is made then a new proxy object will be created which wraps your current object and the call is intercepted.
Am I correct with my assumption?
Second thing is if this process is runtime then what are static pointcuts? when these pointcuts are evaluated?
Your understanding is wrong. A proxy is created only once at startup of the application not each time a method is called on an object. (Unless you have an AOP Scoped Proxy which is prototype scoped, but that scenario is highly unlikely).
#Aspect
public MyAspect {
#Pointcut("execution(* foo.bar.MyService.foo(..)) and args(x, ..)"
public Object around(ProceedingJoinPoint pop, MyObject x) { ... }
}
Given the aspect above the execution(* foo.bar.MyService.foo(..)) is the static part of the joinpoint, it can be matched regardless of inspection of types. The args(x, ..) however is dynamic as it needs to be determined at runtime if the value for x (the first argument in this case) is of type MyObject.
That part cannot be determined statically but only during the actual invocation. Basically anything that depends on runtime informations is dynamic in nature.

Spring AOP: What's the difference between JoinPoint and PointCut?

I'm learning Aspect Oriented Programming concepts and Spring AOP. I'm failing to understand the difference between a Pointcut and a Joinpoint - both of them seem to be the same for me. A Pointcut is where you apply your advice and a Joinpoint is also a place where we can apply our advice. Then what's the difference?
An example of a pointcut can be:
#Pointcut("execution(* * getName()")
What can be an example of a Joinpoint?
Joinpoint: A joinpoint is a candidate point in the Program Execution of the application where an aspect can be plugged in. This point could be a method being called, an exception being thrown, or even a field being modified. These are the points where your aspect’s code can be inserted into the normal flow of your application to add new behavior.
Advice: This is an object which includes API invocations to the system wide concerns representing the action to perform at a joinpoint specified by a point.
Pointcut: A pointcut defines at what joinpoints, the associated Advice should be applied. Advice can be applied at any joinpoint supported by the AOP framework. Of course, you don’t want to apply all of your aspects at all of the possible joinpoints. Pointcuts allow you to specify where you want your advice to be applied. Often you specify these pointcuts using explicit class and method names or through regular expressions that define matching class and method name patterns. Some AOP frameworks allow you to create dynamic pointcuts that determine whether to apply advice based on runtime decisions, such as the value of method parameters.
The following image can help you understand Advice, PointCut, Joinpoints.
Source
Explaination using Restaurant Analogy: Source by #Victor
When you go out to a restaurant, you look at a menu and see several options to choose from. You can order one or more of any of the items on the menu. But until you actually order them, they are just "opportunities to dine". Once you place the order and the waiter brings it to your table, it's a meal.
Joinpoints are options on the menu and Pointcuts are items you select.
A Joinpoint is an opportunity within code for you to apply an aspect...just an opportunity. Once you take that opportunity and select one or more Joinpoints and apply an aspect to them, you've got a Pointcut.
Source Wiki:
A Joinpoint is a point in the control flow of a program where the
control flow can arrive via two different paths(IMO : that's why call
joint).
Advice describes a class of functions which modify other functions
A Pointcut is a matching Pattern of Joinpoint i.e. set of join points.
To understand the difference between a join point and pointcut, think of pointcuts
as specifying the weaving rules and join points as situations satisfying those rules.
In below example,
#Pointcut("execution(* * getName()")
Pointcut defines rules saying, advice should be applied on getName() method present in any class in any package and joinpoints will be a list of all getName() method present in classes so that advice can be applied on these methods.
(In case of Spring, Rule will be applied on managed beans only and advice can be applied to public methods only).
Layman explanation for somebody who is new to the concepts AOP. This is not exhaustive, but should help in grasping the concepts. If you are already familiar with the basic jargon, you can stop reading now.
Assume you have a normal class Employee and you want to do something every time these methods are called.
class Employee{
public String getName(int id){....}
private int getID(String name){...}
}
these methods are called JoinPoints. We need a way to identify these methods so that the framework can find the methods, among all the classes.methods it has loaded.
So we will write a regular expression to match the signature of these methods. While there is more to it as you will see below, but loosely this regular expression is what defines Pointcut. e.g.
* * mypackage.Employee.get*(*)
First * is for modifier public/private/protected/default.
Second * is for return type of the method.
But then you also need to tell two more things:
When should an action be taken -
e.g Before/After the method execution OR on exception
What should it do when it matches (maybe just print a message)
The combination of these two is called Advice.
As you can imagine, you would have to write a function to be able to do #2. So this is how it might look like for the basics.
Note: For clarity, using word REGEX instead of the * * mypackage.Employee.get*(*). In reality the full expression goes into the definition.
#Before("execution(REGEX)")
public void doBeforeLogging() {....} <-- executed before the matching-method is called
#After("execution(REGEX)")
public void doAfterLogging() {....} <-- executed after the matching-method is called
Once you start using these quite a bit, you might end up specifying many #After/#Before/#Around advices. The repeated regular expressions will eventually end up making things confusing and difficult to maintain.
So what we do, we just give a name to the expression and use it everywhere else in the Aspect class.
#Pointcut("execution(REGEX)") <-- Note the introduction of Pointcut keyword
public void allGetterLogging(){} <-- This is usually empty
#Before("allGetterLogging")
public void doBeforeLogging() {....}
#After("allGetterLogging")
public void doAfterLogging() {....}
BTW, you would also want to wrap this whole logic in a class, that is called Aspect and you would write a class:
#Aspect
public class MyAwesomeAspect{....}
To get all these things to work, you would have to tell Spring to parse the classes to read, understand and take action on the # AOP keywords. One way to do it is specifying the following in the spring config xml file:
<aop:aspectj-autoproxy>
JoinPoints: These are basically places in the actual business logic where you wish to insert some miscellaneous functionality that is necessary but not being part of the actual business logic. Some examples of JoinPints are: method call, method returning normally, method throwing an exception, instantiating an object, referring an object, etc...
Pointcuts: Pointcuts are something like regular expressions which are used to identify joinpoints. Pontcuts are expressed using "pointcut expression language". Pointcuts are points of execution flow where the cross-cutting concern needs to be applied. There is a difference between Joinpoint and Pointcut; Joinpoints are more general and represents any control flow where we 'may choose to' introduce a cross-cutting concern while pointcuts identifies such joinpoints where 'we want to' introduce a cross-cutting concern.
Definitions
As per the documentation:
Join point: a point during the execution of a program, such as the
execution of a method or the handling of an exception.
You can consider Joint Points as events in execution of a program. If you are using Spring AOP, this even is limited to invocation of methods. AspectJ provides more flexibility.
But you never handle all events as you don't eat all the food in the menu when you go to a restaurant (I don't know you, you might! But, I certainly don't). So you make a selection of events to handle and what to do with them. Here goes Pointcuts. As per the documentation,
Pointcut: a predicate that matches join points.
Then you associate what to do with the Pointcut, there goes Advice. As per the documentation,
Advice is associated with a pointcut expression and runs at any join point matched by the pointcut.
Code
package com.amanu.example;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
/**
* #author Amanuel Nega on 10/25/16.
*/
class ExampleBussinessClass {
public Object doYourBusiness() {
return new Object();
}
}
#Aspect
class SomeAspect {
#Pointcut("execution(* com.amanu.example.ExampleBussinessClass.doYourBusiness())")
public void somePointCut() {
}//Empty body suffices
#After("somePointCut()")
public void afterSomePointCut() {
//Do what you want to do after the joint point is executed
}
#Before("execution(* *(*))")
public void beforeSomePointCut() {
//Do what you want to do before the joint point is executed
}
}
Explanation of Code
ExampleBusinessClass when proxy-ed, is our target!
doYourBusiness() is a possible joint point
SomeAspect is our aspect that crosses in to multiple concerns such ass ExampleBusinessClass
somePointCut() is a definition of a point cut that matches our joint point
afterSomePointCut() is an advice that will be executed after our somePointCut point cut that matches doYourBusiness() joint point
beforeSomePointCut() is also an advice that matches all public method executions. Unlike afterSomePointCut, this one uses an inline point cut declaration
You can look at the documentation if you don't believe me. I hope this helps
Comparing an AOP language like AspectJ to a data query language like SQL,
you can think of joinpoints (i.e. all places in your code where you can weave aspect code) as a database table with many rows.
A pointcut is like a SELECT stamement which can pick a user-defined subset of rows/joinpoints.
The actual code you weave into those selected places is called advice.
Both pertain to the "where" of aspect-oriented programming.
A join point is an individual place where you can execute code with AOP. E.g. "when a method throws an exception".
A pointcut is a collection of join points. E.g. "when a method in class Foo throws an exception".
JoinPoint: Joinpoint are points in your program execution where flow of execution got changed like Exception catching, Calling other method.
PointCut: PointCut are basically those Joinpoints where you can put your advice(or call aspect).
So basically PointCuts are the subset of JoinPoints.
AOP in spring has {Advisor, Advice, Pointcut, Joinpoint}
As you know the main purpose of aop is decoupling the cross-cutting concern logic (Aspect) from the application code, to implement this in Spring we use (Advice/Advisor)
Pointcut is used to filter where we want to apply this advice exactly, like "all methods start with insert" so other methods will be excluded that's why we have in the Pointcut interface {ClassFilter and MethodMatcher}
So Advice is the cross-cutting logic implementation and Advisor is the advice plus the PointCut, if you use only advice spring will map it to advisor and make the pointcut TRUE which means don't block anything. That's why when you use only advice it is applied to all the methods of the target class because you didn't filter them.
But Joinpoint is a location in the program, you can think about it like reflection when you access the Class object and then you can get Method object, then you can invoke any method in this class, and that's how compiler works, if you think like this you can imagine the Joinpoint.
Joinpoint can be with field, constructor or method but in Spring we have joinpoint with methods only, that's why in Spring we have (Before, After, Throws, Around) types of Joinpoint, all of them refers to locations in the class.
As I mentioned you can have advice with no pointcut (no filter) then it will be applied to all the methods or you can have advisor which is [advice + pointcut] which will be applied to specific methods but you can't have advice without joinpoint like pointcut, you have to specify it, and that's why advice types in spring is exactly the same types as the joinpoint so when you choose an advice you implicitly choose which joinpoint.
To wrap up, advice is the implementation logic for your aspect to the target class, this advice should have a joinpoint like before invocation, after invocation, after throwing or around invocation, then you can filter where exactly you want to apply it using pointcut to filter the methods or no pointcut (no filter) so it will be applied to all the methods of the class.
A pointcut is defined on the Aspect - class implementation. The point cut basically refers to the pointcut expression within the advice.
For e.g,
#Before("execution(* app.purchase2.service.impl.*(..))")
public void includeAddOns(RolesAllowed roles) {
..
}
The above means, "includeAddOns" method is called before invoking(due to the #Before advice) any methods(in classes within package "app.purchase2.service.impl")
The whole annotation is called the pointcut
#Before("execution(* app.purchase2.service.impl.*(..))")
Joint point is the actual method invocation, which joined the method in package "app.purchase2.service.impl" to the method in aspect class "includeAddOns()".
You can access properties of the join point with the org.aspectj.lang.JoinPoint class.
I agree with mgroves.. A point cut can be considered as a collection of multiple joint points. Joint point specify the particular location where the advice could be implemented, where as pointcut reflects the list of all joint points.
JoinPoint: It specifies a point (method) in application where Advice will be executed.
Pointcut: It's a combination of JoinPoints, and it specifies that at which JoinPoint Advice will be executed.
When you go out to a restaurant, you look at a menu and see several options to choose from. You can order one or more of any of the items on the menu. But until you actually order them, they are just "opportunities to dine". Once you place the order and the waiter brings it to your table, it's a meal.
Join points are the options on the menu and pointcuts are the items you select. A joinpoint is an opportunity within code for you to apply an aspect...just an opportunity. Once you take that opportunity and select one or more joinpoints and apply an aspect to them, you've got a pointcut.
PointCut is an annotation, you can declare the scope inside the () where the advice will apply into.
instead, JoinPoint is an interface, it's a parameter used for all the five advice. Especially, for the #Around advice, ProceedingJoinPoint (a child interface of JoinPoint) is applied, and it provides.proceed()method. So you can control if let the program proceed or not. You can also change the args of it.
An Aspect is a package of advices.
e.g.
We have CoffeeService.buildDrink() and BreadService.buildFood().
In AfterSaleApsect.java, there are surveyAdvice() and couponAdvice(), which can be weaved into those services.
To descibe an advice, we need to at least point out 3 things.
When: joinPoint, the scenario that a given event happens.(Such as method execution, exception handling, changing object variable values, etc. In Spring AOP, a join point is always the execution of a method. Ref)
Who: pointcut, the preconditions(expression) for the targets must be matched, or advice will not be executed.
What to do.
#Aspect
public Class AfterSaleApsect{
//#When("Who")
//public void What(){
// ...
//}
//#AfterReturning("execution(* com.example.restaurant.service.*.build*())")
#AfterReturning("myPointcut()")
public void surveyAdvice(){
doSurvey();
}
//#AfterReturning("execution(* com.example.restaurant.service.*.build*())")
#AfterReturning("myPointcut()")
public void couponAdvice(){
doCoupon();
}
//Make it reusable
#Pointcut("execution(* com.example.restaurant.service.*.build*())")
public void myPointcut(){}
}
I think they key difference can be found here:
While aspects define types that crosscut, the AspectJ system does not allow completely arbitrary crosscutting. Rather, aspects define types that cut across principled points in a program's execution. These principled points are called join points.
This means that join points are a well defined sets of places in the execution flow of your application code on which aspect advices can be applied (I.e. a pointcut (or more) placed). You can't just go apply pointcuts willy nilly in your code using AspectJ. The formal definition of the places where pointcuts can be applied are the join points.
The best answer is here
What's the meaning of the method use #Pointcut in Spring AOP,just a pointcut signature?
We use pointcut express language to specify the place that we want to add in code. If there is only one place, we can define it directly in #Before, #After or #Around annotation. If there are multiple places, we can first define each using #Pointcut annotation (with its dummy method). Then we can group them together ( && or ||) and use in #Before, #After or #Around annotation
join point is a place where we actually placing the advices
but the point cut is the collection of join points. that means how many way we con place the cross-cutting logic is called the point cut

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