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

[size=large][b]6.自动代理aop[/b][/size]
自动代理能够让切面的切点定义来决定哪个Bean需要代理,不需要为特定的bean创建代理了。共2种自动代理,spring提供的和aspectJ提供的。
为了[b]使用spring提供的自动代理[/b],要在xml中声明
<!--spring声明的自动代理,它会被自动识别-->    
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>

这样声明,配置文件就不用声明 audienceProxyBase了,也不需要把目标bean改名字叫做xxxxTarget了。方便了许多。Xml配置文件也少了许多。

然而[b]aspectJ提供可一种基于jdk1.5注解技术的方式[/b],使得配置文件更少,更方便
首先,直接把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 />

这样确实是简化了许多。[b]要说明一点:这里只是用@AspectJ的注解作为指导来创建切面,其实质仍人是Spring风格的切面,也就是说,虽然我们用@AspectJ很拉风的写出了切面,但是仍然只能用代理方法调用[/b]

spring自己也意识到,用代理工厂bean,那样代码不好看,所以它提供了另外一种方式,[b]定义纯粹的pojo切面[/b]
它可以把任何类都转换成为切面,这个类没有接口,没有注解,都可以。而且也不用改变原类,全部在配置文件中定义。
现在的 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();
}
}
打印出
观众们找到自己的座位,都坐下来了
请所有观众确定手机已经关闭
表演街舞
观众们大声鼓掌,啪啦啪啦啪啦
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值