Xml代码

- <!--定义完整切面,把定义好的切点和通知放进来就行了 spring定义方式-->
- <bean id="audienceAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
- <property name="pointcut" ref="springpointcut"/>
- <property name="advice" ref="audienceAdvice"/>
- </bean>
- <!--定义完整切面,aspectJ定义方式-->
- <bean id="audienceAdvisor" class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor">
- <property name="expression" value="execution(* Performer+.perform(..))"/>
- <property name="advice" ref="audienceAdvice"/>
- </bean>
切面有了,基本的事情都好了,现在可以想办法把切面用到目标类上了,aop的原理是通过代理实现的,所以我们要声明代理bean了。
首先,之前的ShowBoy和ShowGirl要改在xml中声明的id,他们现在是目标类,所以XML要改为Xml代码

- <bean id="showBoyTarget" class="com.spring.springcase.ShowBoy"/>
- <bean id="showGirlTarget" class="com.spring.springcase.ShowGirl"/>
现在制作一个代理:
Xml代码

- <!--定义代理类,第一个参数是要代理的对象,第2个是使用的切面,第3个是实现的接口-->
- <bean id="showBoy" class="org.springframework.aop.framework.ProxyFactoryBean">
- <property name="target" ref="showBoyTarget"/>
- <property name="interceptorNames">
- <list>
- <value>audienceAdvice</value>
- </list>
- </property>
- <property name="proxyInterfaces">
- <list>
- <value>com.spring.springcase.Perform</value>
- </list>
- </property>
- </bean>
现在就把代理类伪装成showBoy了,为什么要这样,上一篇已经说过了。
现在测试一下
Java代码

- 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();
- }
- }
- 打印结果:
- 观众们找到自己的座位,都坐下来了
- 请所有观众确定手机已经关闭
- 表演街舞
- 观众们大声鼓掌,啪啦啪啦啪啦
如果现在要showGirl也代理,那么就要写它的xml:
Xml代码

- <bean id="showGril" class="org.springframework.aop.framework.ProxyFactoryBean">
- <property name="target" ref="showGirlTarget"/>
- <property name="interceptorNames">
- <list>
- <value>audienceAdvice</value>
- </list>
- </property>
- <property name="proxyInterfaces">
- <list>
- <value>com.spring.springcase.Perform</value>
- </list>
- </property>
- </bean>
如果再有一个呢,那非给把你累死,发现定义代理,大部分代码是一样的,就是引用的目标类不同,这时就要把共有的代码抽出来,自己去写变换的那部分。
定义一个代理的父类,实现了2个参数,其中的目标类由自己写。
Xml代码

- <bean id="audienceProxyBase" class="org.springframework.aop.framework.ProxyFactoryBean" abstract="true">
- <property name="interceptorNames">
- <list>
- <value>audienceAdvice</value>
- </list>
- </property>
- <property name="proxyInterfaces">
- <list>
- <value>com.spring.springcase.Perform</value>
- </list>
- </property>
- </bean>
重新声明伪装类就简单很多了
Xml代码

- <bean id="showBoy" parent="audienceProxyBase">
- <property name="target" ref="showBoyTarget"/>
- </bean>
- <bean id="showGirl" parent="audienceProxyBase">
- <property name="target" ref="showGirlTarget"/>
- </bean>
但是,许多人还是觉得要定义这么一大堆东西,还是太麻烦,没错,我也觉得是麻烦,spring有更好的实现方式。明天再接着总结。
引用
写的不错,不过应该吧xml文件的名称写清楚
所有的xml都写在spring-springcase.xml这个配置文件中