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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

在Eclipse RCP中使用Spring AOP/ProxyFactory的问题

發布時間:2025/3/19 javascript 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在Eclipse RCP中使用Spring AOP/ProxyFactory的问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

也許你還沒有在RCP中用過SPRING,也許你用過,但沒有遇到什么問題,那是因為你只用了簡單的IOC,而沒有用到AOP或是FactoryBean,因此,您并沒有碰到什么問題,但一些很簡單的需求導致我們需在/可以在RCP中使用AOP。
如:
1、需要用到Spring remoting,利用客戶端的invoker訪問遠程的業務,
2、對客戶端的業務聲明事務,你也需要用到類似的東西。
為了盡量將問題最小化,我們只在context中聲明了最少的BEAN,如下:
<bean id="synClient"
?class="com.mudboy.rcp.syncpoc.client.grpclient.GroupClient" singleton="false">
?<property name="synService"><ref bean="syncServerProxy"/></property>
</bean>
<bean? id="syncServerProxy" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
?<property name="serviceUrl"><value>rmi://192.168.40.120:2345/synservice</value></property>???????????????????
<property name="serviceInterface"><value>com.mudboy.rcp.syncpoc.client.grpserver.SynServer</value></property>
</bean>

它聲明了一個調用遠程RMI服務的代理。

很顯然,根據SPRING DEBUG信息,它是在生成syncServerProxy出現了錯誤,異常類型是初始化錯誤,沒有更詳細的信息。其中,我們是在plug-in是使用BEAN相關代碼,并將spring加入到依賴包。


spring 版本是1.2.7
經過一番跟蹤,發現在spring aop機制與rcp classloader存在一些不協調的地方,在下面的代碼中出現了問題:
org.springframework.aop.framework.DefaultAopProxyFactory類中,該方法是產生代理的執行路徑之一:
?
public AopProxy createAopProxy(AdvisedSupport advisedSupport) throws AopConfigException {
??if (advisedSupport.isOptimize() || advisedSupport.isProxyTargetClass() ||
????? advisedSupport.getProxiedInterfaces().length == 0) {
???if (!cglibAvailable) {
????throw new AopConfigException(
??????"Cannot proxy target class because CGLIB2 is not available. " +
??????"Add CGLIB to the class path or specify proxy interfaces.");
???}
???return CglibProxyFactory.createCglibProxy(advisedSupport);
??}
??else {
???return new JdkDynamicAopProxy(advisedSupport);
??}
?}
根據常用設置,代碼走到了return new JdkDynamicAopProxy(advisedSupport);,并在其它調用其(JdkDynamicAopProxy)
public Object getProxy(ClassLoader classLoader)方法。該方法如下:
public Object getProxy(ClassLoader classLoader) {
??if (logger.isDebugEnabled()) {
???Class targetClass = this.advised.getTargetSource().getTargetClass();
???logger.debug("Creating JDK dynamic proxy" +
?????(targetClass != null ? " for [" + targetClass.getName() + "]" : ""));
??}
??Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
??return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
?}
前面,利用ClassUtils.getDefaultClassLoader()得到了默認的classloader并調用了getProxy,結果在
Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);時發生了錯誤(是這JRE里的代碼了)

后來打出了classloader 樹,發生,plug-in應用的classloader只有兩層,并沒有同sun的底層JRE的classloader
關聯起來。因此,你用proxy(JRE)中的動態代理生成的類試圖轉換成根它沒有關系的另一個classloader的一個類
當然會出錯了。

發現這個問題后,定了解決問題的主要思路,就是不用JAVA本身的動態代理,而使用cglib,即讓應用走if的上一個分支,
要讓它走這個分支很簡單,只需簡單的將isOptimize設為true就行,做法:
org/springframework/aop/framework/ProxyFactory
public static Object getProxy(Class proxyInterface, Interceptor interceptor) {
??ProxyFactory proxyFactory = new ProxyFactory();
??proxyFactory.addInterface(proxyInterface);
??proxyFactory.addAdvice(interceptor);
??return proxyFactory.getProxy();
}
中加一句:
proxyFactory.setOptimize(true);即可。


本已為就沒有問題了,查在生成BEAN的時候還是出
了錯,錯誤信息"Either an interface or a target is required for proxy creation",最終定位在了文件:
org.springframework.aop.framework.Cglib2AopProxy,在其構造函數中,有如下語句:
if (config.getTargetSource().getTargetClass() == null) {
?throw new AopConfigException("Either an interface or a target is required for proxy creation");
}

而在整個調用流中,顯然是沒有設置TargetSource,也就是說,用cglib還是有些不太一樣,但看到這代碼的上面有如下
作者的注釋:
//DK - is this check really necessary?
//should this 'config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE' be enough?
于是干脆打它上面的話注掉,記它不作這個檢查,再運行,還是出錯,這次錯誤發生在同一文件的如下方法:
public Object getProxy(ClassLoader classLoader)

Class rootClass = this.advised.getTargetSource().getTargetClass();
用到了TargetSource,其實,其targetClass無非是我的那個接口呀,
com.mudboy.rcp.syncpoc.client.grpserver.SynServer
來個BT一點的,直接將上面這句改為:
Class rootClass = this.advised.getProxiedInterfaces()[0]

后運行應用,OK!!!!太好了,不過,以上修改還是顯得太過草率,但很好去規范化,只是向大家展示一下我遇到的問
題。

總結

以上是生活随笔為你收集整理的在Eclipse RCP中使用Spring AOP/ProxyFactory的问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。