`
DoubleEO
  • 浏览: 154497 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

spring in action学习笔记 3 AOP的自动代理

阅读更多
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();
    }
}
打印出
观众们找到自己的座位,都坐下来了
请所有观众确定手机已经关闭
表演街舞
观众们大声鼓掌,啪啦啪啦啪啦
分享到:
评论
3 楼 Rooock 2009-02-04  
可以附上工程源码吗?
之前我一直使用纯AspectJ做AOP.
现在希望对比下Spring的AOP和AspectJ.
谢谢你.
2 楼 liyun_1981 2009-01-20  
<aop:after-throwing method="takeSeat" pointcut-ref="performance"/>这一句应该是
<aop:after-throwing method="demandRefund" pointcut-ref="performance"/>才对吧。
1 楼 zhangthe9 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



相关推荐

Global site tag (gtag.js) - Google Analytics