AspectjProxyFactory for programmatically creating Aop proxies
A factory for creating Aop agents programmatically has been introduced before ProxyFactory
, which actually ProxyFactory
has all the functions AspectjProxyFactory
. Although they do not have a direct inheritance relationship, they all inherit from ProxyCreatorSupport
, and the core logic of creating proxy objects ProxyCreatorSupport
is implemented in . So it ProxyFactory
has all the functions AspectjProxyFactory
. So what's the difference AspectjProxyFactory
compared ProxyFactory
to? AspectjProxyFactory
The special feature is that it can directly specify the aspect that needs to be bound to the proxy object that needs to be created. When using P roxyFactory
, what we can bind is Advisor
or Advice
, but if we already have an existing aspect class definition in our program and can be used for our newly created proxy class, we also ProxyFactory
need to create a corresponding proxy object. class Advisor
, Advice
class and Pointcut
class definition, which is undoubtedly very cumbersome. AspectjProxyFactory
Typically used to create Aspectj-style Aop proxy objects. Now suppose we have an aspect class definition like the following.
@Aspect
public class MyAspect {
@Pointcut("execution(* add(..))")
private void beforeAdd() {}
@Before("beforeAdd()")
public void before1() {
System.out.println("-----------before-----------");
}
}
In the above aspect class definition, we define one Advisor
, which corresponds to one BeforeAdvice
, in fact, one AspectJMethodBeforeAdvice
, which Advice
corresponds to the above before1()
method, and also corresponds to one Pointcut
, which is actually one AspectJExpressionPointcut
. The Advisor
semantics of this is that calling all methods named "add" will call the method before the call MyAspect.before1()
. If we now need to create a proxy object, the logic that needs to be bound is similar Advisor
to that defined in the aspect class defined above Advisor
. Then we can program as follows.
@Test
public void testAspectJProxyFactory() {
MyService myService = new MyService();
AspectJProxyFactory proxyFactory = new AspectJProxyFactory(myService);
proxyFactory.addAspect(MyAspect.class);
proxyFactory . setProxyTargetClass( true ); // Do you need to use CGLIB to proxy
MyService proxy = proxyFactory . getProxy();
proxy.add();
}
In the above code, we AspectjProxyFactory
need to use the aspect class when creating the proxy object (in fact, addAspect also has an overloaded method that can specify an object of the aspect class), in fact AspectjProxyFactory
, all the aspects contained in the aspect class are parsed internally Advisor
, and then Advisor
Bind the created proxy object that can match the current proxy object class . Interested readers can check AspectjProxyFactory
the source code. The following is some core code.
public void addAspect(Class<?> aspectClass) {
String aspectName = aspectClass.getName();
AspectMetadata am = createAspectMetadata(aspectClass, aspectName);
MetadataAwareAspectInstanceFactory instanceFactory =
createAspectInstanceFactory(am, aspectClass, aspectName);
addAdvisorsFromAspectInstanceFactory(instanceFactory);
}
private void addAdvisorsFromAspectInstanceFactory(
MetadataAwareAspectInstanceFactory instanceFactory) {
List<Advisor> advisors = this.aspectFactory.getAdvisors(instanceFactory);
advisors = AopUtils.findAdvisorsThatCanApply(advisors, getTargetClass());
AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(advisors);
OrderComparator.sort(advisors);
addAdvisors(advisors);
}
It should be noted that
AspectjProxyFactory
when creating a proxy object based on an aspect class, the aspect class we specify must contain the @Aspect annotation.
In addition, it should be noted that although we canAspectjProxyFactory
create@Aspect
proxies for annotation-based aspect classes programmatically, when<aop:aspectj-autoproxy/>
using annotation-based Aspectj-style Aops through configuration, Spring does not pass throughAspectjProxyFactory
the created proxy objects, but through themProxyFactory
. Interested friends can viewAnnotationAwareAspectjAutoProxyCreator
the source code.
(Note: This article is based on Spring 4.1.0, written by Elim on May 9, 2017)