Spring Aop (12) - AspectjProxyFactory for programmatically creating Aop proxy

AspectjProxyFactory for programmatically creating Aop proxies

A factory for creating Aop agents programmatically has been introduced before ProxyFactory, which actually ProxyFactoryhas 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 ProxyCreatorSupportis implemented in . So it ProxyFactoryhas all the functions AspectjProxyFactory. So what's the difference AspectjProxyFactorycompared ProxyFactoryto?
AspectjProxyFactoryThe 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 Advisoror 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 ProxyFactoryneed to create a corresponding proxy object. class Advisor, Adviceclass and Pointcutclass definition, which is undoubtedly very cumbersome. AspectjProxyFactoryTypically 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 Advicecorresponds to the above before1()method, and also corresponds to one Pointcut, which is actually one AspectJExpressionPointcut. The Advisorsemantics 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 Advisorto 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 AspectjProxyFactoryneed 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 AdvisorBind the created proxy object that can match the current proxy object class . Interested readers can check AspectjProxyFactorythe 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 AspectjProxyFactorywhen 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 can AspectjProxyFactorycreate @Aspectproxies for annotation-based aspect classes programmatically, when <aop:aspectj-autoproxy/>using annotation-based Aspectj-style Aops through configuration, Spring does not pass through AspectjProxyFactorythe created proxy objects, but through them ProxyFactory. Interested friends can view AnnotationAwareAspectjAutoProxyCreatorthe source code.

(Note: This article is based on Spring 4.1.0, written by Elim on May 9, 2017)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326218258&siteId=291194637