Spring AOP what is not jointpoint - spring

I need some information about Spring AOP jointpoint. I have read the below in Stackoverflow which explains the difference between jointpoint and pointcut.
As per that joint is
"A joinpoint is a candidate point in the 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."
After reading this to me it looks like every method and field in a class could be a jointpoint. Is there anything which couldn't be a jointput and hence advice couldn't be applied.
Spring AOP: What's the difference between JoinPoint and PointCut?

As for the difference between 'jointpoint' and 'pointcut' you're right so far. A jointpoint is every spot in your code where an aspect might be woven in, whereas a pointcut matches a concrete aspect definition.Acoording to the Spring Documentation, every method of a bean could be defined as a pointcut. Consider that using Spring AOP the definition of pointcuts is limited to method calls. If you're searching for something that supports more sophisticated AOP logic, you may take a look at AspectJ. With AspectJ you're able to choose for example instance beans as pointcuts.

Related

How to use AOP annotation inside method not in method level

I am using Spring AOP to log the DB execution time, but it is applying to the entire method execution time.
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface TrackExecutionTime {
}
Is there any possibility that we can use this #TrackExecutionTime not in the method level but inside a method just above some statement like below -
#TrackExecutionTime
List<Release> releaseList = releaseRepo.findByProductName(productName.toUpperCase());
that way I can able to get only the DB execution time not only the entire method execution time, as my method contains other business logic too which also including if we use the AOP annotation at the method level.
Your question is not AOP-specific, because annotations are a Java language feature. The answer is: Annotations on arbitrary lines of code are not part of the Java language concept, which for you means you also cannot use them for AOP purposes. This is simply a Java limitation. Neither Spring AOP nor native AspectJ can support a feature which does not exist in Java to begin with.
Friendly suggestion: Please learn more about Java first, then get acquainted with some basic software design and clean code principles. Finally, you shall be able to achieve what you want, albeit in a different way from what you just dreamed up here.
Spring AOP default configuration uses proxies to execute the aspect hence only methods can be annotated.
A bit of a detour on the proxies. A proxy wraps a target method so when you call a method elsewhere Spring makes sure to invoke the method on the proxy and that invocation then contains the aspect code which gets executed before, after, around the call itself (depending on the aspect). There can be several proxies wrapping a single class.
Then an option is to add your aspect annotation to the repository method.
If we need to track the execution time only for subset of calls to the method (which sounds a bit strange a requirement) then we can add a wrapper method - say make a Spring-managed Metrics class with a said time tracking method that accepts a lambda and is annotated with the #TrackExecutionTime. The original call would then be something like
metrics.executeTimed(() -> releaseRepo.findByProductName(productName.toUpperCase()));

Spring AOP Prototype-scoped Aspects are Firing out-of-order

I am using a set of Spring AOP Aspects (mostly from my library here). I am finding that the ordering I specify for the aspects is no longer being respected (I am certain that, at some point in the past, say, 1 year ago on Boot 1.3.x, it was respected) when the scope of the aspect bean is "prototype". If I remove the 'scope="prototype"' in XML, or the #Scope("prototype") in JavaConfig, the ordering is correct, but when the scope is prototype the ordering does not work - the aspects fire in apparently random order. The aspects implement the Ordered interface.
Bean definitions follow the pattern (JavaConfig):
#Bean
#Scope("prototype")
public CircuitBreakerAspect circuitBreakerAspect()
{
CircuitBreakerAspect aspect = new CircuitBreakerAspect();
aspect.setGraphiteClient(graphiteClient);
aspect.setOrder(100);
return aspect;
}
I need the aspects to be prototype scope, because some of them (e.g., RetryInterceptor) are stateful (maintaining a count of failed operations, which is exported to JMX). If I remove the prototype scope, the ordering works correctly but the same singleton aspect instance is used for all advised bean instances!
I am on Spring Boot 1.4.1 and Java 8.
How can I get prototype aspects to order correctly?
I don't think that the prototype scope is supported for aspects or more likely it does not make sense. Documentation at 11.2.6 Aspect instantiation models specifically mentions this:
By default there will be a single instance of each aspect within the
application context.
To modify this behaviour, Spring AOP supports AspectJ perthis and pertarget instantiation models. Perhaps they will be useful to you.
This appears to be a bug in Spring. If I add the #Order annotation to the aspects, they order properly. I've submitted a bug with Spring. https://jira.spring.io/browse/SPR-14959

Before pointcut on HttpServletResponse sendRedirect compiling but not firing

I'm currently trying to add a pointcut around calls to HttpServletResponse.sendRedirect (api doc http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletResponse.html) using aspectj and spring aop. The code for the class and pointcut are as follows:
#Aspect
#Log4j
class ExampleAspect {
#Before("execution(* javax.servlet.http.HttpServletResponse.sendRedirect(..))")
void logRedirectBeforeSending() {
log.warn('holy cow batman, its a redirect!')
}
}
Currently although the above code compiles it doesn't actually ever execute (as evidenced by a lack of warn output in the log and debug breakpoints in the advice code never being hit).
Although I've omitted them here just for the sake of simplicity the aspect contains other pointcuts which do correctly fire so I have ruled out aspect configuration as a potential cause (which is why I am not including my spring bean configuration).
Further, I have double checked via debugging that a class which implements HttpServletResponse.sendRedirect() is being called when I'm testing my pointcut (if it helps, one of the implementing classes being called is org.apache.catalina.connector.Response https://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/connector/Response.html).
Is there something I'm missing in my pointcut definition that's required when defining a pointcut around an interface? Best I could tell from the Spring AOP documentation it shouldn't require any special syntax.
I've been playing around with variations in the pointcut definition but haven't had any luck yet.
All in all I'm stumped, any ideas?
I expect that your response object is not coming from the Spring application context and as such it would not be subject to your aspect.
It doesn't matter that the call is being initiated from a Spring bean. It matters that the call is being invoked on a Spring bean. If you for example wrote a point cut to be applied to the append method in StringBuffer and then you did something like new StringBuffer().append('something'), your point cut would not be applied because the StringBuffer that you are interacting with is not a Spring bean. I don't know how your app is put together but unless your response is coming out of the Spring context, I don't expect your point cut to be applied.

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

Can we log inside a method using AOP?

I want to log some statements in my method using AOP.
I am able to define the pointcuts, advice for method starting, ending, exception scenarios.
Can we log in between the method at some point (after method entry and before execution finishes?) I am using Spring 3.0.
No, it is not possible. Spring is not capable of "looking into" your methods and modifying them. Technically AspectJ weaving can do this, but I would stay away from such approaches.
What you can do is to extract methods, which will not only allow you to provide some finer-grained logging, but you will also improve the overall code quality. However note that by default Spring can only intercept public (proxies) and protected methods (CGLIB).

Resources