版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SDDDLLL/article/details/86627498
在上一篇博客中,看到我们前面通知或者是顾问所使用的代理对象,都是使用的是ProxyFactoryBean,这个代理存在着以下几个缺点:
- 一个代理对象只能代理一个bean。
- 在测试代码中我们使用的id是代理类的id,不是目标类的id。(看下面)
既然有很大的缺点,肯定就有解决办法,spring容器提供了自动代理生成器,用于解决上面的问题。常用的自动代理生成器有两个:
- 默认顾问自动代理生成器
- bean名称自动代理生成器
需要说明的是,这两个都是继承2自BeanPostProcessor。它没有id,所有测试类(客户类)直接使用目标对象的id。
下面直接通过代码说明:
一、默认Advisor自动代理生成器
1、修改配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 注册两个目标对象-->
<bean id="someService" class="com.fdd.aop11.SomeServiceImpl"></bean>
<bean id="someService2" class="com.fdd.aop11.SomeServiceImpl"></bean>
<!-- 注册切面:通知 -->
<bean id="myAdvice" class="com.fdd.aop11.MyAfterReturningAdvice"> </bean>
<!-- 切面注册:顾问 -->
<bean id="myAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" ref="myAdvice"></property>
<property name="pattern" value=".*doFirst"></property>
</bean>
<!-- 注册自动代理生成器 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"> </bean>
</beans>
2、修改测试代码
@Test
public void test01(){
String resource = "com/fdd/aop11/applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(resource);
ISomeService service =(ISomeService) ac.getBean("someService");
System.out.println("=====");
String a=service.doFirst();
System.out.println("=====");
service.doSecond();
System.out.println("=====");
service.doThird();
ISomeService service2 =(ISomeService) ac.getBean("someService2");
System.out.println("=====");
String a1=service2.doFirst();
System.out.println("=====");
service2.doSecond();
System.out.println("=====");
service2.doThird();
}
看结果
从上图中我们可以看到,我们只是注册了一个自动代理生成器,但是植入了两个切面。
二、bean名称自动代理生成器
bean名称自动代理生成器是根据bean的id,找出符合相应名称的代理对象的,切面既可以是顾问又可以是通知。
此时的实现方式跟之前略有不同:
1、两个接口实现类
2、配置文件修改
- beanNames:指定要增强的目标类的id
- interceptorNames:指定切面,可以使顾问,也可以是通知。
<!--
DefaultAdvisorAutoProxyCreator存在三个问题
1)不能选择目标对象
2)不能选择切面类型,切面只能是advisor
3)不能选择advisor,所以advisor均将被作为切面织入到目标方法
-->