spring心得9--自動代理知識點講解及案例分析

y_keven發表於2013-05-07

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>



 

相關文章