日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring AOP 的proxy详解

發(fā)布時間:2025/5/22 javascript 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring AOP 的proxy详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

spring 提供了多種不同的方案實現(xiàn)對 bean 的 aop proxy, 包括 ProxyFactoryBean, 便利的 TransactionProxyFactoryBean 以及 AutoProxyCreator 等,
下圖是 proxy class diagram 以供參考

這里重點說一下最常用的 ProxyFactoryBean, TransactionProxyFactoryBean, BeanNameAutoProxyCreator, DefaultAdvisorAutoProxyCreator 的聯(lián)系和區(qū)別

1. ProxyFactoryBean : 使用率最高的 proxy 方式, 它通過配置 interceptorNames 屬性決定加入哪些 advisor (method interceptor 將會被自動包裝成 advisor, 下文將描述這個細節(jié)),
注意是 "interceptorNames" 而不是 "interceptors",

原因是 ProxyFactoryBean 可能返回非 singleton 的 proxy 實例, 而 advisior 可能也是非 singleton 的,

因此不能通過 interceptor reference 來注入

2. TransactionProxyFactoryBean : 特定用于 transaction proxy, 注意其 super class 是 AbstractSingletonProxyFactoryBean, 也就是說,

TransactionProxyFactoryBean 永遠無法返回非 singleton 的 proxy 實例 !!!

如果你需要非 singleton 的 proxy 實例, 請考慮使用 ProxyFactoryBean.

3. BeanNameAutoProxyCreator : 故名思義, 根據(jù) bean name 進行 auto proxy, bean name 的 match 規(guī)則參見 org.springframework.util.PatternMatchUtils

4. DefaultAdvisorAutoProxyCreator : 更強大的 auto proxy creator, 強大之處在于它會 cahce 容器中所有注冊的 advisor, 然后搜索容器中所有的 bean ,
如果某個 bean 滿足 advisor 中的 Pointcut, 那么將會被自動代理, 與 BeanNameAutoProxyCreator 相比, 省去了配置 beanNames 的工作,

?

引用:
eg :??????

  • ???<bean?class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"?/> ??
  • ?<bean?id="defaultPointcutAdvisor"?class="org.springframework.aop.support.DefaultPointcutAdvisor"?scope="prototype"> ??
  • ????????<property?name="pointcut"?ref="fooPointcut"/> ??
  • ????????<property?name="advice"?ref="fooAdvice"/> ??
  • </bean>??? ??
  • ??
  • <bean?id="fooAdvice"?class="com.mycompany.FooAdvice"?scope="prototype"?/> ??
  • ??
  • <bean?id="fooPointcut"?class="org.springframework.aop.support.JdkRegexpMethodPointcut"?scope="prototype"> ??
  • ????????<property?name="patterns"> ??
  • ????????????<list> ??
  • ????????????????<value>com.mycompany.FooService.*</value> ??
  • ????????????</list> ??
  • ????????</property> ??
  • ????</bean> ??
  • ????
  • [java] view plaincopy
  • ????
  • ???<bean?class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"?/>??
  • ?<bean?id="defaultPointcutAdvisor"?class="org.springframework.aop.support.DefaultPointcutAdvisor"?scope="prototype">??
  • ????????<property?name="pointcut"?ref="fooPointcut"/>??
  • ????????<property?name="advice"?ref="fooAdvice"/>??
  • </bean>?????
  • ??
  • <bean?id="fooAdvice"?class="com.mycompany.FooAdvice"?scope="prototype"?/>??
  • ??
  • <bean?id="fooPointcut"?class="org.springframework.aop.support.JdkRegexpMethodPointcut"?scope="prototype">??
  • ????????<property?name="patterns">??
  • ????????????<list>??
  • ????????????????<value>com.mycompany.FooService.*</value>??
  • ????????????</list>??
  • ????????</property>??
  • ????</bean>??
  • ????


  • 以上配置將自動代理容器中所有 com.mycompany.FooService 類型的 bean, 并攔截其所有方法

    深度話題

    1. MethodInterceptor 如何被包裝成 Advisor ?

    在 AdvisorAdapterRegistry#wrap(Object) 方法中實現(xiàn), code as below

  • public?Advisor?wrap(Object?adviceObject)?throws?UnknownAdviceTypeException?{ ??
  • ??if?(adviceObject?instanceof?Advisor)?{ ??
  • ????return?(Advisor)?adviceObject; ??
  • ??} ??
  • ??if?(!(adviceObject?instanceof?Advice))?{ ??
  • ????hrow?new?UnknownAdviceTypeException(adviceObject); ??
  • ??} ??
  • ??Advice?advice?=?(Advice)?adviceObject; ??
  • ??if?(advice?instanceof?MethodInterceptor)?{ ??
  • ???//?So?well-known?it?doesn't?even?need?an?adapter. ??
  • ???return?new?DefaultPointcutAdvisor(advice); ??
  • ??} ??
  • ??for?(int?i?=?0;?i?<?this.adapters.size();?i++)?{ ??
  • ???/?Check?that?it?is?supported. ??
  • ???????????????????????????????AdvisorAdapter?adapter?=?(AdvisorAdapter)?this.adapters.get(i); ??
  • if?(adapter.supportsAdvice(advice))?{ ??
  • ?????????????????????????????????return?new?DefaultPointcutAdvisor(advice); ??
  • ?} ??
  • } ??
  • ??throw?new?UnknownAdviceTypeException(advice); ??
  • ????????????????????} ??
  • ???????????
  • [java] view plaincopy
  • public?Advisor?wrap(Object?adviceObject)?throws?UnknownAdviceTypeException?{??
  • ??if?(adviceObject?instanceof?Advisor)?{??
  • ????return?(Advisor)?adviceObject;??
  • ??}??
  • ??if?(!(adviceObject?instanceof?Advice))?{??
  • ????hrow?new?UnknownAdviceTypeException(adviceObject);??
  • ??}??
  • ??Advice?advice?=?(Advice)?adviceObject;??
  • ??if?(advice?instanceof?MethodInterceptor)?{??
  • ???//?So?well-known?it?doesn't?even?need?an?adapter.??
  • ???return?new?DefaultPointcutAdvisor(advice);??
  • ??}??
  • ??for?(int?i?=?0;?i?<?this.adapters.size();?i++)?{??
  • ???/?Check?that?it?is?supported.??
  • ???????????????????????????????AdvisorAdapter?adapter?=?(AdvisorAdapter)?this.adapters.get(i);??
  • if?(adapter.supportsAdvice(advice))?{??
  • ?????????????????????????????????return?new?DefaultPointcutAdvisor(advice);??
  • ?}??
  • }??
  • ??throw?new?UnknownAdviceTypeException(advice);??
  • ????????????????????}??
  • ???????????


  • 從代碼可以看到, 如果 adviceObject(也就是 interceptorNames 對應(yīng)的 bean) 不是 advisor
    而是 MethodInterceptor 或 Advice, 那么 spring 將其包裝成 DefaultPointcutAdvisor,
    而 DefaultPointcutAdvisor 中定義的 Pointcut 是 TruePointcut :

  • ????class?TruePointcut?implements?Pointcut,?Serializable?{ ??
  • ??
  • ????public?static?final?TruePointcut?INSTANCE?=?new?TruePointcut(); ??
  • ???? ??
  • ????/** ?
  • ?????*?Enforce?Singleton?pattern. ?
  • ?????*/??
  • ????private?TruePointcut()?{ ??
  • ????} ??
  • ??
  • ????public?ClassFilter?getClassFilter()?{ ??
  • ????????return?ClassFilter.TRUE; ??
  • ????} ??
  • ??
  • ????public?MethodMatcher?getMethodMatcher()?{ ??
  • ????????return?MethodMatcher.TRUE; ??
  • ????} ??
  • ???? ??
  • ????/** ?
  • ?????*?Required?to?support?serialization.?Replaces?with?canonical ?
  • ?????*?instance?on?deserialization,?protecting?Singleton?pattern. ?
  • ?????*?Alternative?to?overriding?<code>equals()</code>. ?
  • ?????*/??
  • ????private?Object?readResolve()?{ ??
  • ????????return?INSTANCE; ??
  • ????} ??
  • ??
  • ????public?String?toString()?{ ??
  • ????????return?"Pointcut.TRUE"; ??
  • ????} ??
  • ??
  • } ??
  • ???? ??
  • ??????
  • [java] view plaincopy
  • ????class?TruePointcut?implements?Pointcut,?Serializable?{??
  • ??
  • ????public?static?final?TruePointcut?INSTANCE?=?new?TruePointcut();??
  • ??????
  • ????/**?
  • ?????*?Enforce?Singleton?pattern.?
  • ?????*/??
  • ????private?TruePointcut()?{??
  • ????}??
  • ??
  • ????public?ClassFilter?getClassFilter()?{??
  • ????????return?ClassFilter.TRUE;??
  • ????}??
  • ??
  • ????public?MethodMatcher?getMethodMatcher()?{??
  • ????????return?MethodMatcher.TRUE;??
  • ????}??
  • ??????
  • ????/**?
  • ?????*?Required?to?support?serialization.?Replaces?with?canonical?
  • ?????*?instance?on?deserialization,?protecting?Singleton?pattern.?
  • ?????*?Alternative?to?overriding?<code>equals()</code>.?
  • ?????*/??
  • ????private?Object?readResolve()?{??
  • ????????return?INSTANCE;??
  • ????}??
  • ??
  • ????public?String?toString()?{??
  • ????????return?"Pointcut.TRUE";??
  • ????}??
  • ??
  • }??
  • ??????
  • ??????


  • 也就是說, MethodInterceptor 和 Advice 被包裝成的 Advisor 將會匹配容器中的所有 bean,
    所以, 永 遠不要在 DefaultAdvisorAutoProxyCreator 的 interceptorNames 中引用一個 Advice, 那將會使容器中所有的 bean 被自動代理!!! 此時應(yīng)該考慮使用 BeanNameAutoProxyCreator

    轉(zhuǎn)載于:https://www.cnblogs.com/hanxue112253/p/3878181.html

    總結(jié)

    以上是生活随笔為你收集整理的Spring AOP 的proxy详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。