1.自动代理知识点介绍

    自动代理的产生原因:

    有许多类需要通知时,显式的创建每个代理就会显得很笨拙。spring有一个自动代理机制,它可以让容器为我们产生代理。自动代理类分两种,分别是以下两种:

BeanNameAutoProxyCreator、DefaultAdvisorAutoProxyCreator

  BeanNameAutoProxyCreator

  该类为匹配一系列名字的Bean自动创建代理。这种名字匹配和前面讲到的NameMethodMatherPointcut类似,他也允许在名字的两端进行通配符。通常为符合相同命名规则的bean应用一个或一组切面。

  DefaultAdvisorAutoProxyCreator

  该类实现了BeanPostProcessor接口。当应用上下文读入所有的Bean的配置信息后,该类将扫描上下文,寻找所有的Advisor。他将这些Advisor应用到所有符合切入点的Bean中。很重要的一点是这个代理创建器只能与Advisor配合使用。该类需要Advisor来知道哪些Bean需要通知。

2.自动代理案例分析

1BeanNameAutoProxyCreator类自动代理案例剖析

    该案例的讲解是基于前面讲各种通知的例子,这里只列出配置文件和测试类(该测试一下测试了以下三种自动代理案例的知识点测试),如果需要参看抽象主题和真实主题,可以去看上一篇博客spring各种通知的案例讲解

sprin配置文件:spring-byNameAutoAdvisor.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">

  <!-- 创建前置通知 -->
  <bean id="beforeAdvice" class="www.csdn.spring.proxy.advice.BeforeAdvice"/>
  <!-- 创建后置通知 -->
  <bean id="afterAdvice" class="www.csdn.spring.proxy.advice.AfterAdvice"/>
  <!-- 创建环绕通知 -->
  <bean id="aroundAdvice" class="www.csdn.spring.proxy.advice.AroundAdvice"/>
  <!-- 创建异常通知 -->
  <bean id="throwAdvice" class="www.csdn.spring.proxy.advice.ThrowAdvice"/>


  <!-- 真实主题   目标对象 -->
  <bean id="sayServiceImpl" class="www.csdn.spring.proxy.advice.SayServiceImpl"/>
  
  
  <!-- 配置自动代理操作 -->
  <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
     <property name="beanNames">
       <list>
         <!-- <value>*ServiceImpl</value> -->
        <value>*Service*</value>
       </list>
     </property>
     <property name="interceptorNames">
       <array>
          <value>aroundAdvice</value>
       </array>
     </property>
  </bean>
</beans>

测试类  AutoAdvisorTest.java

package www.csdn.spring.proxy.advice;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AutoAdvisorTest {

	@Test
	public void testAdvice() {
		// 默认自动代理测试
		ApplicationContext context = new ClassPathXmlApplicationContext(
				"spring-default*.xml");
		/*
		 * 自动代理测试 ApplicationContext context = new
		 * ClassPathXmlApplicationContext( "spring-byNameAuto*.xml");
		 */
		SayService sayService = context.getBean("sayServiceImpl",
				SayService.class);
		sayService.say("嗨!杨凯!");
	}
}


 

2) DefaultAdvisorAutoProxyCreator类自动代理基于静态切入点案例分析

sprin配置文件:spring-defaultStaticAutoAdvisor.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">

  <!-- 创建前置通知 -->
  <bean id="beforeAdvice" class="www.csdn.spring.proxy.advice.BeforeAdvice"/>
  <!-- 创建后置通知 -->
  <bean id="afterAdvice" class="www.csdn.spring.proxy.advice.AfterAdvice"/>
  <!-- 创建环绕通知 -->
  <bean id="aroundAdvice" class="www.csdn.spring.proxy.advice.AroundAdvice"/>
  <!-- 创建异常通知 -->
  <bean id="throwAdvice" class="www.csdn.spring.proxy.advice.ThrowAdvice"/>
  
  
  <!-- 静态切入点 -->
  <bean id="nameMatchMethodPointcutAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
    <!-- 织入通知,比如环绕通知 -->
    <property name="advice">
      <ref bean="aroundAdvice"/>
    </property>
    <!-- 指明切入点 -->
    <property name="mappedName">
      <value>say</value>
    </property>
  </bean>
  

  <!-- 真实主题   目标对象 -->
  <bean id="sayServiceImpl" class="www.csdn.spring.proxy.advice.SayServiceImpl"/>
  
  
  <!-- 配置默认的自动代理操作 -->
  <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
</beans>


 

3) DefaultAdvisorAutoProxyCreator类自动代理基于正则切入点案例分析

sprin配置文件:spring-defaultRegAutoAdvisor.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">

  <!-- 创建环绕通知 -->
  <bean id="aroundAdvice" class="www.csdn.spring.proxy.advice.AroundAdvice"/>
   
  
  <!-- 静态切入点 -->
  <bean id="regexpMethodPointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
    <!-- 织入通知,比如环绕通知 -->
    <property name="advice">
      <ref bean="aroundAdvice"/>
    </property>
    <!-- 指明切入点 -->
    <property name="patterns">
    <!-- .是通配符的意思;第一个.*代表匹配任何包名和类名 ;第二个.*代表匹配以say开头的任意方法-->
      <array>
      <!-- 
      <value>.*sayH.</value>
      <value>.*bye.*</value>
      <value>www.*\.SayService\.sayHell.</value> 
      <value>.+sayH.*</value>
      -->
      <value>.+sayH\..+</value>
      </array>
    </property>
  </bean>
  

  <!-- 真实主题   目标对象 -->
  <bean id="sayServiceImpl" class="www.csdn.spring.proxy.advice.SayServiceImpl"/>
  
  
 <!-- 配置默认的自动代理操作 -->
  <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
</beans>



 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐