`
234390216
  • 浏览: 10193892 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
A5ee55b9-a463-3d09-9c78-0c0cf33198cd
Oracle基础
浏览量:460812
Ad26f909-6440-35a9-b4e9-9aea825bd38e
springMVC介绍
浏览量:1771850
Ce363057-ae4d-3ee1-bb46-e7b51a722a4b
Mybatis简介
浏览量:1395469
Bdeb91ad-cf8a-3fe9-942a-3710073b4000
Spring整合JMS
浏览量:393909
5cbbde67-7cd5-313c-95c2-4185389601e7
Ehcache简介
浏览量:678239
Cc1c0708-ccc2-3d20-ba47-d40e04440682
Cas简介
浏览量:529311
51592fc3-854c-34f4-9eff-cb82d993ab3a
Spring Securi...
浏览量:1178754
23e1c30e-ef8c-3702-aa3c-e83277ffca91
Spring基础知识
浏览量:461973
4af1c81c-eb9d-365f-b759-07685a32156e
Spring Aop介绍
浏览量:150157
2f926891-9e7a-3ce2-a074-3acb2aaf2584
JAXB简介
浏览量:66872
社区版块
存档分类
最新评论

Spring Aop(十二)——编程式的创建Aop代理之AspectjProxyFactory

阅读更多

编程式的创建Aop代理之AspectjProxyFactory

之前已经介绍了一款编程式的创建Aop代理的工厂——ProxyFactory,其实ProxyFactory拥有的功能AspectjProxyFactory都有。它们虽然没有直接的继承关系,但是它们都继承自ProxyCreatorSupport,而创建代理对象的核心逻辑都是在ProxyCreatorSupport中实现的。所以说ProxyFactory拥有的功能AspectjProxyFactory都有。那么AspectjProxyFactoryProxyFactory相比有什么不同呢?
AspectjProxyFactory的特殊之处就在于其可以直接指定需要创建的代理对象需要绑定的切面。在使用ProxyFactory时,我们能够绑定的是AdvisorAdvice,但是如果我们的程序中已经有了现成的切面类定义且能够为我们新创建的代理类使用时,我们还要为了ProxyFactory建立代理对象的需要创建对应的Advisor类、Advice类和Pointcut类定义,这无疑是非常麻烦的。AspectjProxyFactory通常用于创建基于Aspectj风格的Aop代理对象。现假设我们有如下这样一个切面类定义。

@Aspect
public class MyAspect {

	@Pointcut("execution(* add(..))")
	private void beforeAdd() {}
	
	@Before("beforeAdd()")
	public void before1() {
		System.out.println("-----------before-----------");
	}
	
}

在上述切面类定义中我们定义了一个Advisor,其对应了一个BeforeAdvice,实际上是一个AspectJMethodBeforeAdvice,该Advice对应的是上面的before1()方法,还对应了一个Pointcut,实际上是一个AspectJExpressionPointcut。该Advisor的语义就是调用所有的方法名为“add”的方法时都将在调用前调用MyAspect.before1()方法。如果我们现在需要创建一个代理对象,其需要绑定的Advisor逻辑跟上面定义的切面类中定义的Advisor类似。则我们可以进行如下编程。

@Test
public void testAspectJProxyFactory() {
	MyService myService = new MyService();
	AspectJProxyFactory proxyFactory = new AspectJProxyFactory(myService);
	proxyFactory.addAspect(MyAspect.class);
	proxyFactory.setProxyTargetClass(true);//是否需要使用CGLIB代理
	MyService proxy = proxyFactory.getProxy();
	proxy.add();
}

在上述代码中我们AspectjProxyFactory在创建代理对象时需要使用的切面类(其实addAspect还有一个重载的方法可以指定一个切面类的对象),其实在AspectjProxyFactory内部还是解析了该切面类中包含的所有的Advisor,然后把能够匹配当前代理对象类的Advisor与创建的代理对象绑定了。有兴趣的读者可以查看一下AspectjProxyFactory的源码,以下是部分核心代码。

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);
}

需要注意的是在使用AspectjProxyFactory基于切面类创建代理对象时,我们指定的切面类上必须包含@Aspect注解。
另外需要注意的是虽然我们自己通过编程的方式可以通过AspectjProxyFactory创建基于@Aspect标注的切面类的代理,但是通过配置<aop:aspectj-autoproxy/>使用基于注解的Aspectj风格的Aop时,Spring内部不是通过AspectjProxyFactory创建的代理对象,而是通过ProxyFactory。有兴趣的朋友可以查看一下AnnotationAwareAspectjAutoProxyCreator的源代码。

(注:本文是基于Spring4.1.0所写,Elim写于2017年5月9日)

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics