I am reading a book, which talks about enabling AspectJ support in Spring AOP.
Given below is a paragraph taken from the book:
To enable AspectJ annotation support in the Spring IoC container, you only have to define an empty
XML element aop:aspectj-autoproxy in your bean configuration file. Then, Spring will automatically
create proxies for any of your beans that are matched by your AspectJ aspects.
For cases in which interfaces are not available or not used in an application’s design, it’s possible to
create proxies by relying on CGLIB. To enable CGLIB, you need to set the attribute proxy-target-class=true
in <aop:aspectj-autoproxy />
.
I am not able to get the second paragraph. What is meant by 'interfaces are not available'. Can anyone illustrate this with an example ?
Spring AOP uses either JDK dynamic proxies or CGLIB to create the proxies for your target objects.
According to Spring documentation, in case your target implements at least one interface, a JDK dynamic proxy will be used. However if your target object does not implement any interfaces then a CGLIB proxy will be created.
This is how you can force creation of the CGLIB proxies (set proxy-target-class="true"):
<aop:config proxy-target-class="true">
<!-- other beans defined here... -->
</aop:config>
When using AspectJ and its autopoxy support you can also force CGLIB proxies. This is where the <aop:aspectj-autoproxy>
is used and also here the "proxy-target-class" must be set to true:
<aop:aspectj-autoproxy proxy-target-class="true"/>
Please refer to Proxying mechanisms section of Aspect Oriented Programming with Spring documentation for more details.
Spring prefers to use interfaces for AOP because it can use JDK proxies.
Say for example I have an interface MyService
public interface MyService {
void doSomething();
}
And an implementation MyServiceImpl
@Service
public class MyServiceImpl implements MyService {
public void doSomething() {
// does something!
}
}
If Spring discovers that you've configured aspects for MyService
, it will create a JDK Proxy that implements MyService
and then proxy all calls through to your MyServiceImpl
bean, adding aspect functionality where appropriate.
JDK proxies work by implementing the same interface as your target object and delegating calls to it; they do not work if there is no interface to implement. In case you don't have an interface like above, Spring needs to use a byte code library like CGLIB to dynamically create classes at runtime that incorporate the aspect functionality.
I found a blog here that clearly explains how AOP,Caching & Transaction works using runtime proxy classes.
When not coding to interface (quoting from the blog's section 'What if the bean class does not implement any interface?'):-
By default, if your bean does not implement an interface, Spring uses
technical inheritance: at startup time, a new class is created. It
inherits from your bean class and adds behavior in the child methods.
In order to generate such proxies, Spring uses a third party library
called cglib.
Spring AOP makes extensive use of proxies as a mechanism to implement cross-cutting concerns (a.k.a aspects) in a non-intrusive way, the idea basically is use the proxies as wrappers that enrich the original behaviour, i.e. add transactional capabilities.
To achieve this there are two options, depending of whether the original object implements an interface or not.
In the first case (the original object implements at least one interface) the dynamic proxy capabilities of the reflection API are used to create a proxy object that IMPLEMENTS the same interfaces that the original object and therefore the proxy can be used instead.
In the second case (the original object does NOT implement any interface), so a more elaborated trick must be used, and this is when CGLIB appears. According to the project page "CGLIB is used to extend Java classes and implements interfaces at runtime". So in this case the trick consists on create a proxy that EXTENDS the original object and therefore can be used instead.