Log message on Spring AOP Aspect start up - spring

how to log message on Spring AOP aspect start up?
The only way I see is to specify flag on every intercepted method and check. May be any other options? Thanks

If you want to get that line every time a pointcut is done by Spring AOP, you could
pointcut all the AOP methods with a new pointcut
make all pointcuts extend some super-pointcut
which you target to write that line.
If you want to have the AOP class write something when it gets loaded, you can use #BeforeClass to have it do something before the class gets used.

Related

How #Aspect with #Component annotation works under the hood

I've been looking for an answer for a while, but no luck so far, thus I'm coming here for some words of wisdom.
I've created an aspect using #Aspect annotation, because I need to #Autowire some singleton dependencies I've decided to annotate this aspect class with #Component and let the Spring to do the magic. It works, however ...
I'm fairly familiar with AOP concept, what's weaving and different flavors of it (cglib vs aspectj) but it's not fully intuitive to me how it works under the hood.
#Component means a given class will be a singleton within a given context, #Aspect means that the content of an aspect class will be somehow weaved into the target class during runtime/compilation - and this target class is not a singleton but prototype for instance. So what I'm ending up with at the end?
Spring AOP does not do compile-time-weaving and does not modify the code of the advised target. Instead it works with proxies that are weaved around the joinpoints. That is why Spring AOP aspects and be used as (singleton) components, have their fields autowired, etc., like any other Spring Proxy.
It is also the reason why Spring AOP aspects only work for public method executions, not field accesses and the like.
The documentation is quite well written and goes into as much (or as little) detail as one might like:
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html
The book AspectJ in Action's section 2.5 is on the internal working of the weaving step, it is only 2 page but gets the point across well.
Luckily the section is available here.
This is for posterity.

Spring AOP Method Interceptor vs Method Advice

I am new to AOP and I am trying to understand the difference between Method Interceptor and MethodAdvice(i.e. MethodBeforeAdvice or MethodAfterAdvice). To me looks like both are doing the same thing i.e. are called on method invocation. When should we use MethodInterceptor vs MethodAdvice.
Take a look at the definition of the org.aopalliance.interceptInterceptor interface (implemented by MethodInterceptor):
public interface Interceptor extends Advice {
}
It's easy to see that a MethodInterceptor actually IS an Advice.
The only difference between an Advice being defined in an #Aspect class and such an Interceptor is that Interceptor implementations can be added to and removed from Spring AOP Proxies at runtime (casting them to 'Advised'), whereas the Advice you're talking about is a more static construct. But their still essential to Spring AOP since their presence tells Spring which beans to wrap in a proxy object during application context startup.

What are the other use of Spring AOP except Logging and Exception handling?

Spring AOP and AspectJ are usually used for Exception handling and Logging. Is there any other feature for which we are using aspectJ and spring AOP.
Yes, transactional behavior is the first to come to mind. Take a look at the #Transactional annotation. You mark a method with the annotation and the container will take the necessary steps to start a transaction before your method executes and commit or roll back the transaction when it ends.
Security is another nice application of AOP. You can annotate a method to mark it as requiring certain permissions. For example, in a web application, you might have a few handler methods for requests that require the user to be an administrator. Instead of implementing that logic in each handler method, you extract it to some AOP advice and put a joinpoint at each of those methods.
Aspects can be used as any type of filter really. You can allow, prevent, modify access to a method.
Note that Spring's support for AOP is limited to method invocation join points.

Spring DefaultAdvisorAutoProxyCreator with #Transactional causing problems

I'm working on a Spring MVC project and trying to integrate Apache Shiro for the security. Everything was going just swimmingly until I realized Hibernate was prematurely closing the session/connection after a single query and causing a lazyinit exception. Not surprising, what I was doing should be done within a transaction so the session isn't closed.
Dilemmas…
I tried putting #Transactional on my controller method, but I get 404's then. Looking at my logs, I can see that when Spring is bootstrapping it ignores any mappings in my HomeController if that #Transactional annotation is on any method within the controller.
Without the #Transactional and it loads up just fine, and Ih can see the RequestMappingHandlerMapping bean sees all the #RequestMapping annotations in my controller.
With #Transactional but without DefaultAdvisorAutoProxyCreator, and it works except Shiro annotations are simply ignored.
tldr: Shiro requires DefaultAdvisorAutoProxyCreator, but if I create that bean, Spring blows up when using the #Transactional annotation.
I'm asking for help because I'm completely at a loss for how to proceed at this point.
This is typically because when you put #Transactional on a method, Spring creates a dynamic proxy for that bean - if the bean implements an interface then dynamic proxy is created based on that interface, otherwise CGLIB will be used for creating the proxy.
The problem in your case, I am guessing is because you probably have based your controller on some interface, or you are extending it based on a base class. This is ending up creating a proxy based on that interface, because of this when it comes time for mappings to be created for your request, Spring MVC is probably not finding your mappings from your bean.
The fix could be a few:
a. You can try and force proxies to be based on CGLIB for your transactions:
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
b. You can use pure Aspectj,either load time weaving or compile time weaving
c. You can move the #Transactional into a Service (which has an interface) and delegate the call from the controller to the service, this way avoiding #Transaction on the controller

How to add a custom annotation to Spring MVC?

Can anyone explain what I need to do to implement my own annotation that would add functionality to my web requests?
For example:
#Controller
public class MyController {
#RequestMapping("/abc")
#RequiresSomeSpecialHandling
public void handleSecureRequest() {
}
}
Here #RequiresSomeSpecialHandling would be my own annotation that causes some special work to be done before or after the given web request /abc.
I know that on a very high level I would need to write a bean post processor, scan classes for my annotations, and inject custom mvc interceptors when needed. But are there any shortcuts to simplify this task? Especially for the two examples above.
Thanks in advance,
This kind of Annotations, (that add additional functionality when invoking a method) looks like annotations that trigger an AOP Advice.
#see Spring Reference Chapter 7. Aspect Oriented Programming with Spring
The idea is to use the Annotation to trigger the AOP Advice.
like:
#Pointcut("#target(com.example.RequiresAuth)")
Depends on what you want to do as a result of #RequiresSomeSpecialHandling. E.g. do you want it to influence request mappings or the invocation of the method (i.e. resolving method arguments, processing the return value)?
The support for annotated classes in Spring 3.1 became much more customizable. You can browse some examples in this repo.
Also keep in mind that a HandlerInterceptor in Spring 3.1 can cast the handler Object to HandlerMethod, which gives you access to the exact method including its annotations. That may be enough for what you need to do.
If caching is one of your goals, take a look at the #Cacheable annotation (and its siblings #CachePut, #CacheEvict and #Caching), available as of Spring 3.1.

Resources