Spring AOP 自動創建代理


    Spring為我們提供了自動代理機制,讓容器為我們自動生成代理,把我們從煩瑣的配置工作中解放出來,在內部,Spring 使用BeanPostProcessor自動地完成這項工作。
 

1、實現類介紹

    這些基於BeanPostProcessor的自動代理創建器的實現類,將根據一些規則自動在容器實例化Bean時為匹配的Bean生成代理實例。
    1)基於Bean配置名規則的自動代理創建器:允許為一組特定配置名的Bean自動創建代理實例的代理創建器,實現類為BeanNameAutoProxyCreator;
    2)基於Advisor匹配機制的自動代理創建器:它會對容器中所有的Advisor進行掃描,自動將這些切面應用到匹配的Bean中(即為目標Bean創建代理實例),實現類為DefaultAdvisorAutoProxyCreator;
    3)基於Bean中AspjectJ注解標簽的自動代理創建器:為包含AspectJ注解的Bean自動創建代理實例,它的實現類是AnnotationAwareAspectJAutoProxyCreator,該類是Spring 2.0的新增類。
 
2、BeanNameAutoProxyCreator
Waiter業務類:
package com.yyq.aop;
 
public class Waiter {
    public void greetTo(String name) {
        System.out.println("waiter greet to " + name + ".");
    }
 
    public void serveTo(String name) {
        System.out.println("waiter serving to " + name + ".");
    }
}

 Seller業務類:

package com.yyq.aop;
 
public class Seller {
    public void greetTo(String name) {
        System.out.println("seller greet to " + name + ".");
    }
}

GreetingBeforeAdvice前置增強實現類:

package com.yyq.aop;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
 
public class GreetingBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println(o.getClass().getName() + "." + method.getName());
        String clientName = (String) objects[0];
        System.out.println("Hi! Mr." + clientName + ".");
    }
}

使用Bean名進行自動代理配置:

<bean id="waiterTarget" class="com.yyq.aop.Waiter"/>
<bean id="sellerTarget" class="com.yyq.aop.Seller"/>
<bean id="greetingAdvice" class="com.yyq.aop.GreetingBeforeAdvice"/>
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"
       p:beanNames="*Target"
       p:interceptorNames="greetingAdvice"
       p:optimize="true"/>
    BeanNameAutoProxyCreator 有一個beanNames屬性,它允許用戶指定一組需要自動代理的Bean名稱,Bean名稱可以使用 * 通配符。
測試方法:
@Test
    public void testAdvisor6(){
        String configPath = "com\\yyq\\aop\\beans.xml";
        ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);
        Waiter waiter = (Waiter)ctx.getBean("waiterTarget");
        Seller seller = (Seller)ctx.getBean("sellerTarget");
        waiter.greetTo("Peter");
        seller.greetTo("Tom");
    }

輸出結果:

com.yyq.aop.Waiter.greetTo
Hi! Mr.Peter.
waiter greet to Peter.
com.yyq.aop.Seller.greetTo
Hi! Mr.Tom.
seller greet to Tom.
 
3、DefaultAdvisorAutoProxyCreator
    Advisor是切點和增強的復合體,Advisor本身已經包含了足夠的信息:橫切邏輯(要織入什么)以及連接點(織入到哪里)。DefaultAdvisorAutoProxyCreator能夠掃描容器中的Advisor,並將Advisor自動織入到匹配的目標Bean中,即為匹配的目標Bean自動創建代理。
配置:
<bean id="waiterTarget" class="com.yyq.aop.Waiter"/>
<bean id="sellerTarget" class="com.yyq.aop.Seller"/>
<bean id="greetingAdvice" class="com.yyq.aop.GreetingBeforeAdvice"/>
<bean id="regexpAdvisor2" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"
          p:pattern=".*greet.*"
          p:advice-ref="greetingAdvice"/>
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>

測試方法:

@Test
    public void testAdvisor7(){
        String configPath = "com\\yyq\\aop\\beans.xml";
        ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);
        Waiter waiter = (Waiter)ctx.getBean("waiterTarget");
        Seller seller = (Seller)ctx.getBean("sellerTarget");
        waiter.greetTo("Peter");
        waiter.serveTo("Peter");
        seller.greetTo("Tom");
    }
輸出結果:
com.yyq.aop.Waiter.greetTo
Hi! Mr.Peter.
waiter greet to Peter.
waiter serving to Peter.
com.yyq.aop.Seller.greetTo
Hi! Mr.Tom.
seller greet to Tom.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM