簡體   English   中英

用Cglib2AopProxy代理的對象上的Canot調用set方法

[英]Canot call set method on a object that's proxied with Cglib2AopProxy

以下代碼在單元測試中工作正常,在該單元測試中,我在代碼中構建了測試夾具。 如果我創建一個單元測試,在spring config xml文件中定義必要的bean,它也可以正常工作。 但是,當我將代碼和上下文文件部署到Java EE容器時,它不起作用。

public class QuicCsvUpdaterChains {
    private Map<Process, QuicCsvUpdater> updateChains = new Hashtable<Process, QuicCsvUpdater>();

    public QuicCsvUpdaterChains() {}

    public QuicCsvUpdaterChains(Map<Process, List<QuicCsvUpdater>> updaters) {

    Set<Entry<Process, List<QuicCsvUpdater>>> entrySet = updaters.entrySet();

    for(Entry<Process, List<QuicCsvUpdater>> entry : entrySet) {
        updateChains.put(entry.getKey(), join(new ArrayList<QuicCsvUpdater>(entry.getValue())));
    }
}


private QuicCsvUpdater join(List<QuicCsvUpdater> updaters) {

    if(updaters.size() == 1) {
        return updaters.remove(0);
    }

    QuicCsvUpdater updater = updaters.remove(0);
    QuicCsvUpdater next = join(updaters);
    updater.setNextInChain(next);
    return updater;
}

updater.setNextInChain(next)的調用實際上從未在更新程序上實際設置next。 從在調試器中進入updater.setNextInChain(next)行的調試器中可以看到,在Cglib2AopProxy中,設置調用發生在目標上,但代理從未更新。

為什么會在Cglib2AopProxy中更新目標,但從未更新代理以反映更改?

在Cglib2AopProxy中,我進入這一行

else {
                // We need to create a method invocation...
                retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
            }

我看到的是'setNextInChain'方法是在目標而不是代理上調用的,我假設代理需要更新,因為在我調用updater.setNextInChain(next)代碼中,它是我持有的代理參考。

我做這項工作的唯一方法是從切入點中明確排除類。 無論出於何種原因,我發現如果滿足以下條件:

class A {
    private A next;

    public setNext(A next) {
        this.next = next;
    }
}

然后是以下spring配置:

<bean id="firstA" class="A"/>
<bean id="secondA" class="A" p:next="firstA"/>

初始化bean工廠時,將發生對secondA的setNext(...)的調用,但是當我嘗試使用secondA時,next始終為null。 正如我說的那樣,這在不存在方面的單元測試中非常有效,所以我唯一的選擇是在切入點表達式中排除A。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM