Spring学习(8)AOP之自动代理生成器

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SDDDLLL/article/details/86627498

在上一篇博客中,看到我们前面通知或者是顾问所使用的代理对象,都是使用的是ProxyFactoryBean,这个代理存在着以下几个缺点:

  • 一个代理对象只能代理一个bean。
  • 在测试代码中我们使用的id是代理类的id,不是目标类的id。(看下面)

既然有很大的缺点,肯定就有解决办法,spring容器提供了自动代理生成器,用于解决上面的问题。常用的自动代理生成器有两个:

  1. 默认顾问自动代理生成器
  2. 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均将被作为切面织入到目标方法
	
	 -->

3、看测试类 

猜你喜欢

转载自blog.csdn.net/SDDDLLL/article/details/86627498
今日推荐