Can we log inside a method using AOP? - spring

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).

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 what is not jointpoint

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.

Spring Weaving: #Configurable objects do not get woven correctly if used as a Parameter inside Methods of Autoproxies

Please consider following situation with spring 4.0.7
For Eclipselink, we use a load-time-weaver. So we wanted to experiment with Springs #Configurable annotation using #EnableSpringConfigured with #EnableLoadTimeWeaving at the same time.
This is fully functional, and Spring-Beans are injected perfectly into POJOs during construction. This functionality is helpful for us, because we want to keep some code regarding validation of these POJOs inside these and not somewhere else in a Bean.
SOme of our Spring Context contains Beans that do not implement any interface, because they are local to some package and used only there. Lets say, FooLogicBean is one of them. If this is to be injected into another Bean, and some Spring-AOP-Aspect (not-aspectj) like some performance measurement aspect is in the execution path, Spring will create a CGLIB autoproxy for the FooLogicBean and inject that. This is fully functional and works perfectly too.
Problems arise, when we want to actually use a POJO that is annotated with #Configurable as a parameter in a method of FooLogicBean (like fooLogicBean.doValidate(myPojo); ), respectively a CGLIB Proxy. In this case, some non-trivial magic stops that POJO from being woven thru aspectj (AnnotationBeanConfigurerAspect from spring-aspects). It is even never woven anywhere in the code regardless of calling the aforementioned doValidate() Method.
If we create that POJO inside FooLogicBean, but dont use it as a method Parameter, it gets woven again due to #Configurable.
Without knowing the Autoproxy creation code, we assume some fancy marking routine from hindering a class from being detected by aspectj, if that class was already used in spring-aop. use in this case means Access.
Did anyone experiment with such obscure constellation and knows a solution for that?
Thanks in advance!
Proxies are created by subclassing, i.e. when you create a proxy of an annotated class Foo:
class Foo {
#Bar
void bar() { }
}
the proxy is created by implementing a class
class Foo$Proxy extends Foo {
#Override
void bar() {
// Proxy logic
}
// Overridden methods of Object
}
This makes the Foo$Proxy class a valid Liskov substitute for Foo. However, normal override semantics apply, i.e. non-inherited annotations such as #Bar are not longer present for the overridden methods. Once another annotation-based API processes your beans, all annotations have disappeared which leads to your outcome. This is true for all kinds of annotations. Those on types, methods and method parameters.
But is it avoidable? It most certainly is by using a proxy generator that was written recently and is built with knowledge of what annotations are, something that is not true for cglib which was first shipped in the early days of the Java virtual machine. However, as long as Spring does not move away from cglib, you will have to live with today's limitations.

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.

Can I inject code in spring using AOP annotations?

Is it possible to do something like the following:
public void doStuff(#RequirePrivilege("foo") User user) {
// ...
}
and have it effectively run as if it were the following?
public void doStuff(User user) {
if(!user.hasPrivilege("foo"))
throw new UserHasInsufficientPrivileges(); // this is a RuntimeException
// ...
}
I know that Spring has various sorts of AOP support, but the best I could find was AOP code which was annotated so that it would execute before or after a specific method. I want to do the inverse and annotate the code that should be changed.
Ultimately I could just do the above check inside the method, but the annotation way of doing things provides additional documentation which makes it obvious that the user requires a particular privilege without having to keep the documentation in sync with the code.
You can look at using AspectJ for doing this, as it will match on annotations. You can then use an around aspect to decide if the user meets the requirements to use this method.
Spring allows you to use AspectJ, and I would suggest that if possible you not do this at run-time, but at compile-time, as there is no reason to pay the price for using this aspect whenever you start the application. But, if you must do it at run-time then that is doable, to me I try to use compile-time as much as possible.
You may want to look at AspectJ In Action (http://www.manning.com/laddad2/) but here is an example from there:
Signature pattern:
* *(#RequestParam
(#Sensitive *))
Description
*Any method with one parameter marked with the #RequestParam annotations and the parameter’s type is marked with the #Sensitive annotation.*
Example
void create(#RequestParam
MedicalRecord mr), assuming
MedicalRecord carries the
#Sensitive annotation.
I'm certain that your "insufficient privileges" example can be done with Spring AOP, because that's how Spring Security works. You can do some very sophisticated things with around advice and AspectJ.

Resources