简体   繁体   English

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

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

The following code works fine from a unit test where I build up the test fixture in code. 以下代码在单元测试中工作正常,在该单元测试中,我在代码中构建了测试夹具。 It also works fine if I create a unit test where I define the necessary beans in a spring config xml file. 如果我创建一个单元测试,在spring config xml文件中定义必要的bean,它也可以正常工作。 It doesn't work however when I deploy the code and context file to a Java EE container. 但是,当我将代码和上下文文件部署到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;
}

The call to updater.setNextInChain(next) never actually sets next on the updater. updater.setNextInChain(next)的调用实际上从未在更新程序上实际设置next。 From what I can see in the debugger stepping in at the line updater.setNextInChain(next) , in Cglib2AopProxy the call to set takes place on the target but the proxy is never updated. 从在调试器中进入updater.setNextInChain(next)行的调试器中可以看到,在Cglib2AopProxy中,设置调用发生在目标上,但代理从未更新。

Why would it be that in Cglib2AopProxy the target is updated but the proxy is never updated to reflect the change? 为什么会在Cglib2AopProxy中更新目标,但从未更新代理以反映更改?

In Cglib2AopProxy I get to this line 在Cglib2AopProxy中,我进入这一行

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

What I see is that the 'setNextInChain' method is called on the target but not on the proxy, I'm presuming the proxy needs to be updated becuase in my code where I call updater.setNextInChain(next) it's the proxy that I hold a reference to. 我看到的是'setNextInChain'方法是在目标而不是代理上调用的,我假设代理需要更新,因为在我调用updater.setNextInChain(next)代码中,它是我持有的代理参考。

The only way I could make this work was to explicitly exclude the classes from the pointcut. 我做这项工作的唯一方法是从切入点中明确排除类。 For what ever reason, I found that if I had the following: 无论出于何种原因,我发现如果满足以下条件:

class A {
    private A next;

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

and then the following spring config: 然后是以下spring配置:

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

When the bean factory was initialised the call to setNext(...) on secondA would happen but then when I tried to use secondA, next would always be null. 初始化bean工厂时,将发生对secondA的setNext(...)的调用,但是当我尝试使用secondA时,next始终为null。 As I say this worked perfectly in a unit test where the aspect was not present so my only option has been to exclude A in the pointcut expression. 正如我说的那样,这在不存在方面的单元测试中非常有效,所以我唯一的选择是在切入点表达式中排除A。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM