java.lang.NoSuchMethodException: $Proxy

回想明天發表於2012-08-15

今天遇到這麼一個異常,原來是對action進行了代理,這個是在spring的配置檔案中的。所以,修改掉就正常了。

 

如何修改呢?

1. 加入代理的話,那麼action 中就要有如下方法。

   <property name="transactionAttributes">
            <props>
                <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>


2. 不配置代理。。


3. aop:config proxy-target-class="true">  
    <aop:aspect ref="rightFilter">  
        <aop:before method="rightFilter" pointcut="execution(* com.exdoit.action.Main.mainPage())"></aop:before>  
        <aop:after method="actionAfter" pointcut="execution(* com.exdoit.action.Main.mainPage())"></aop:after>  
    </aop:aspect>  
</aop:config> 
<aop:config proxy-target-class="true">
 <aop:aspect ref="rightFilter">
  <aop:before method="rightFilter" pointcut="execution(* com.exdoit.action.Main.mainPage())"></aop:before>
  <aop:after method="actionAfter" pointcut="execution(* com.exdoit.action.Main.mainPage())"></aop:after>
 </aop:aspect>
</aop:config>

起先是使用的annotation註解,然後出問題找不到 proxy-target-class 怎麼註解就轉成XML了.

java.lang.NoSuchMethodException: $Proxy...
先是代理物件裡找不到方法.問題是解決了.

spring中代理物件的生成方式有2種,

1:利用jdk中的proxy實現,要求我們的被代理物件必須要去實現一個代理介面,代理物件和被代理物件本質是是實現了統一介面的兩個物件

2:利用cglib來實現.被代理物件不需要去實現一個代理介面,被代理類和代理類之間本質是父子類的關係

proxy-target-class="true" 是指定由cglib來實現實現代理.

解決方法(2種):

1.取消繼承 com.opensymphony.xwork2.ActionSupport 放棄這種方法
2.配置檔案裡的 <aop:config proxy-target-class="true" >....</aop:config>
繼續AOP許可權控制測試又報如下錯誤
Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.
沒有新增 cglib.jar 的包...你說沒包你就跟下面的 NoClassDefFoundError 提示一樣不得了..還自己來個什麼 Add CGLIB to the class...搞半天才明白是少包了.

...繼續

nested exception is java.lang.NoClassDefFoundError : Could not initialize class...

根據提示找包就是了.簡單的問題.

執行結果是 AOP 攔截成功實現,但是action的變數沒有輸出結果...
如 public String nextPath;直接使用public宣告取不到值(不用AOP前是可以直接通過public宣告取值的).需要為變數加一個 get 方法:
public String getNextPath(){return nextPath;}
當請求一個變數的時候,轉為尋找這個變數get方法的返回值.

估計應該是AOP的動態代理機制導致公共變數在action對應的方法中修改不會被實現


相關文章