Canot在使用Cglib2AopProxy代理的对象上调用set方法

时间:2015-03-05 20:08:41

标签: java spring cglib

以下代码在单元测试中工作正常,我在代码中构建了测试夹具。如果我创建一个单元测试,我在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)的调用永远不会在更新程序上实际设置下一个。从我在调试器中看到的线路updater.setNextInChain(next)踩到的, 在Cglib2AopProxy中,对set的调用发生在目标上,但代理永远不会更新。

为什么在Cglib2AopProxy中更新目标但是代理永远不会更新以反映更改?

在Cglib2AopProxy中,我到了这一行

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

我看到的是&#39; setNextInChain&#39;方法是在目标上调用而不是在代理上调用,我假设代理需要更新,因为在我的代码中我调用updater.setNextInChain(next)它是我持有引用的代理。

1 个答案:

答案 0 :(得分:0)

我能做这项工作的唯一方法是明确地从切入点中排除类。出于某种原因,我发现如果我有以下内容:

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.