Spring AOP 自動建立代理
目錄
4、DefaultAdvisorAutoProxyCreator
1、概述
在學習切面的時候,都是通過ProxyFactoryBean建立織入切面的代理,每個需要被代理Bean都需要使用一個ProxyFactoryBean進行配置,很是麻煩。Spring為我們提供了自動代理機制,Spring 使用BeanPostProcessor自動地完成這項工作,讓容器為我們自動生成代理,把我們從煩瑣的配置工作中解放出來。
BeanPostProcessor介面如下,定義了兩個方法
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
2、實現類介紹
這些基於BeanPostProcessor的自動代理建立器的實現類,將根據一些規則自動在容器例項化Bean時為匹配的Bean生成代理例項。這些自動代理建立器可以分為3類。
a、基於Bean配置名規則的自動代理建立器:允許為一組特定配置名的Bean自動建立代理例項的代理建立器,實現類為BeanNameAutoProxyCreator;
b、基於Advisor匹配機制的自動代理建立器:它會對容器中所有的Advisor進行掃描,自動將這些切面應用到匹配的Bean中(即為目標Bean建立代理例項),實現類為DefaultAdvisorAutoProxyCreator;
c、基於Bean中AspjectJ註解標籤的自動代理建立器:為包含AspectJ註解的Bean自動建立代理例項,它的實現類是AnnotationAwareAspectJAutoProxyCreator。
3、BeanNameAutoProxyCreator的使用
程式碼例子依舊使用前面建立切面的程式碼,建立切面的例子中是使用ProxyFactoryBean對Waiter的Bean建立代理物件(建立切面程式碼地址:https://blog.csdn.net/u012385190/article/details/81952302)。下面通過BeanNameAutoProxyCreator以更優雅、更便捷的方式來建立代理物件
xml配置如下
<!-- 前置增強 -->
<bean id="greetBeforeAdvice" class="demo04.advisor.GreetBeforeAdivce"/>
<!-- Waiter目標類 -->
<bean id="waiterTarget" class="demo04.advisor.Waiter"/>
<!-- Seller目標類 -->
<bean id="seller" class="demo04.advisor.Seller"/>
<!--根據beanName建立代理物件-->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"
p:beanNames="*Target"
p:interceptorNames="greetBeforeAdvice"
p:optimize="true"/>
測試類
//一組特定配置名的Bean自動建立代理例項的代理建立器
@Test
public void test() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans/beans2.xml");
Waiter waiter = ctx.getBean("waiterTarget", Waiter.class);
Seller seller = ctx.getBean("seller", Seller.class);
waiter.greetTo("JayChou");
waiter.serverTo("JayChou");
seller.greetTo("JayChou");
}
輸出(beanNames="*Target",該bean的方法都會使用增強)
How are you JayChou ?(切點方法為:public void demo04.advisor.Waiter.greetTo(java.lang.String))
Waiter Greet to JayChou
How are you JayChou ?(切點方法為:public void demo04.advisor.Waiter.serverTo(java.lang.String))
Waiter Server to JayChou
Seller Greet to JayChou
從輸出結果可以看出,BeanNameAutoProxyCreator有一個beanNames屬性,它允許使用者指定一組需要自動建立代理的Bean名稱,Bean名稱可以使用 * 萬用字元。但是使用匹配符可能會匹配到多餘的bean,所以也可以使用beanNames=“bean1,bean2”,用逗號分隔開多個要生成代理物件的bean。
4、DefaultAdvisorAutoProxyCreator
Advisor是切點和增強的複合體(切面),Advisor本身已經包含了足夠的資訊:橫切邏輯(要織入什麼)以及連線點(織入到哪裡)。DefaultAdvisorAutoProxyCreator能夠掃描容器中的Advisor,並將Advisor自動織入到匹配的目標Bean中,即為匹配的目標Bean自動建立代理。
<!--定義一個切面Advisor-->
<bean id="regexpAdvisor2" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"
p:pattern=".*greet.*"
p:advice-ref="greetingAdvice"/>
<!--該bean負責將容器中的Advisor織入匹配的目標bean中-->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
測試
@Test
public void test() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans/beans2.xml");
Waiter waiter = ctx.getBean("waiterTarget", Waiter.class);
Seller seller = ctx.getBean("seller", Seller.class);
waiter.greetTo("JayChou");
waiter.serverTo("JayChou");
seller.greetTo("JayChou");
}
輸出
How are you JayChou ?(切點方法為:public void demo04.advisor.Waiter.greetTo(java.lang.String))
Waiter Greet to JayChou
Waiter Server to JayChou
How are you JayChou ?(切點方法為:public void demo04.advisor.Seller.greetTo(java.lang.String))
Seller Greet to JayChou
Waiter#serverTo()方法沒有被織入增強,而Waiter和Seller的greetTo()方法都被織入了增強,由此可見,增強被正確的織入匹配的連線點中了。
相關文章
- 死磕Spring之AOP篇 - Spring AOP自動代理(三)建立代理物件Spring物件
- 死磕Spring之AOP篇 - Spring AOP自動代理(一)入口Spring
- AOP詳解之三-建立AOP代理後記,建立AOP代理
- 死磕Spring之AOP篇 - Spring AOP自動代理(二)篩選合適的通知器Spring
- Spring AOP --JDK動態代理方式SpringJDK
- Spring框架系列(10) - Spring AOP實現原理詳解之AOP代理的建立Spring框架
- spring aop原理 JDK動態代理和CGLIB動態代理SpringJDKCGLib
- 從動態代理到Spring AOP(中)Spring
- 從動態代理到Spring AOP(上)Spring
- Spring AOP 實現《自動自動填充Entity》Spring
- 【Spring AOP】AOP 底層實現原理 —— 動態代理類的建立(JDK、CGlib)、工廠如何加工原始物件SpringJDKCGLib物件
- Spring AOP代理執行解析Spring
- 3種代理模式-理解Spring Aop模式Spring
- 從代理機制到Spring AOPSpring
- 這一次搞懂Spring代理建立及AOP鏈式呼叫過程Spring
- 淺析Spring中AOP的實現原理——動態代理Spring
- Java動態代理(AOP)Java
- Spring自學之路---AOPSpring
- Spring AOP裡的靜態代理和動態代理,你真的瞭解嘛?Spring
- AOP原始碼解析之二-建立AOP代理前傳,獲取AOP資訊原始碼
- AOP之靜態代理VS動態代理
- 死磕Spring之AOP篇 - Spring AOP兩種代理物件的攔截處理Spring物件
- spring上 -基於註解配置bean,動態代理,AOP筆記SpringBean筆記
- 淺析DispatchProxy動態代理AOP
- 死磕Spring之AOP篇 - 初識JDK、CGLIB兩種動態代理SpringJDKCGLib
- JAVA-Spring AOP基礎 - 代理設計模式JavaSpring設計模式
- 【Spring】AOP的代理預設是Jdk還是Cglib?SpringJDKCGLib
- 建立屬於自己的 Spring Boot 自動配置Spring Boot
- Spring 動態代理Spring
- spring動態代理Spring
- 死磕Spring之AOP篇 - Spring AOP註解驅動與XML配置SpringXML
- Spring AOP 中被代理的物件一定是單例嗎?Spring物件單例
- [Spring]AOPSpring
- spring AOPSpring
- Spring框架系列(12) - Spring AOP實現原理詳解之JDK代理實現Spring框架JDK
- Spring框架系列(11) - Spring AOP實現原理詳解之Cglib代理實現Spring框架CGLib
- AOP - 自己寫 JDK 動態代理增強 beanJDKBean
- JAVA_動態代理AOP切面程式設計Java程式設計