浏览 4003 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-12-26
6.自动代理aop
自动代理能够让切面的切点定义来决定哪个Bean需要代理,不需要为特定的bean创建代理了。共2种自动代理,spring提供的和aspectJ提供的。 为了使用spring提供的自动代理,要在xml中声明 <!--spring声明的自动代理,它会被自动识别--> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/> 这样声明,配置文件就不用声明 audienceProxyBase了,也不需要把目标bean改名字叫做xxxxTarget了。方便了许多。Xml配置文件也少了许多。 然而aspectJ提供可一种基于jdk1.5注解技术的方式,使得配置文件更少,更方便 首先,直接把Audience类改造成切面。首先要有aspectjweaver 这个jar包,具体代码如下,全部用了注解来声明切面中各个元素,通俗易懂。 @Aspect public class Audience { public Audience() { } @Pointcut("execution(* *.perform(..))") public void performance(){} @Before("performance()") public void takeSeat(){ System.out.println("观众们找到自己的座位,都坐下来了"); } @Before("performance()") public void turnOffMobilePhone(){ System.out.println("请所有观众确定手机已经关闭"); } @AfterReturning("performance()") public void appluad(){ System.out.println("观众们大声鼓掌,啪啦啪啦啪啦"); } @AfterThrowing public void demandRefund(){ System.out.println("演的太差了,我们要退钱!"); } } 其中 @Pointcut("execution(* *.perform(..))") public void performance(){} performance方法没有实际意义,它只是为了让切点注解 @Pointcut("execution(* *.perform(..))")附在它身上而已,注解必须要附在字段或者方法上,才有意义。 现在只要在xml中声明 <bean id="audience" class="com.spring.springcase.Audience"/> 这个声明, audience已经就是切面了,再也不用在xml里定义什么切点和通知了,再次大大简化。 现在要做的是,声明一个aspectJ提供的自动代理bean,让他能自动把切面用到方法上。 我们用spring的aop空间的提供的一个自定义配置元素。 现在xml头部声明就变成了 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"> 现在所有的xml加起来,是这样的了: <bean id="showBoy" class="com.spring.springcase.ShowBoy"/> <bean id="showGirl" class="com.spring.springcase.ShowGirl"/> <bean id="audience" class="com.spring.springcase.Audience"/> <aop:aspectj-autoproxy /> 这样确实是简化了许多。要说明一点:这里只是用@AspectJ的注解作为指导来创建切面,其实质仍人是Spring风格的切面,也就是说,虽然我们用@AspectJ很拉风的写出了切面,但是仍然只能用代理方法调用 spring自己也意识到,用代理工厂bean,那样代码不好看,所以它提供了另外一种方式,定义纯粹的pojo切面 它可以把任何类都转换成为切面,这个类没有接口,没有注解,都可以。而且也不用改变原类,全部在配置文件中定义。 现在的 Audience又变回原来那个普通的bean了。我们要把这个普通的bean,配置成切面 public class Audience { public Audience() { } public void takeSeat(){ System.out.println("观众们找到自己的座位,都坐下来了"); } public void turnOffMobilePhone(){ System.out.println("请所有观众确定手机已经关闭"); } public void appluad(){ System.out.println("观众们大声鼓掌,啪啦啪啦啪啦"); } public void demandRefund(){ System.out.println("演的太差了,我们要退钱!"); } } <bean id="audience" class="com.spring.springcase.Audience"/> <aop:config> <aop:aspect ref="audience"> <aop:pointcut id="performance" expression="execution(* *.perform(..))"/> <aop:before method="takeSeat" pointcut-ref="performance"/> <aop:before method="turnOffMobilePhone" pointcut-ref="performance"/> <aop:after-returning method="appluad" pointcut-ref="performance"/> <aop:after-throwing method="takeSeat" pointcut-ref="performance"/> </aop:aspect> </aop:config> 这样就可以了 运行一下测试 public class performTest extends TestCase{ ApplicationContext ctx; @Override protected void setUp() throws Exception { ctx = new ClassPathXmlApplicationContext("spring-springcase.xml"); } public void testShowBoy(){ Perform perform = (Perform)ctx.getBean("showBoy"); perform.perform(); } public void testShowGirl(){ Perform perform = (Perform)ctx.getBean("showGirl"); perform.perform(); } } 打印出 观众们找到自己的座位,都坐下来了 请所有观众确定手机已经关闭 表演街舞 观众们大声鼓掌,啪啦啪啦啪啦 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-01-20
前面一个例子
@Aspect public class Audience { 这个的 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'showBoy' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Must set property 'expression' before attempting to match |
|
返回顶楼 | |
发表时间:2009-01-20
<aop:after-throwing method="takeSeat" pointcut-ref="performance"/>这一句应该是
<aop:after-throwing method="demandRefund" pointcut-ref="performance"/>才对吧。 |
|
返回顶楼 | |
发表时间:2009-02-04
可以附上工程源码吗?
之前我一直使用纯AspectJ做AOP. 现在希望对比下Spring的AOP和AspectJ. 谢谢你. |
|
返回顶楼 | |