Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
388 views
in Technique[技术] by (71.8m points)

java - Is it possible to unproxy a Spring bean?

I have a Spring bean, let's say:

@TransactionAttribute(TransactionAttributeType.REQUIRED) 
public class AImpl implements A {

     public void setSomeDependency(D dependency) {
         // This setter DOES NOT BELONG to interface A
     }
}

<bean id="aImpl" class="AImpl"/>

Now I want to integration test it, but first I need to mock the dependency D, because it does too much stuff. Since the AImpl implements an interface and contains a transactional annotation, the generated proxy is only compatible with the interface A, so I can do this:

@Inject @Named("aImpl")
private A a;

but cannot:

@Inject @Named("aImpl")
private AImpl a;

As a result, I can't mock my dependency.

Please note that adding void setSomeDependency(D dependency) to interface A is not an option, as it has no business meaning. Neither it is using the proxy-target-class="true", as it breaks a whole lot of other beans (this attribute affects all beans in the context).

Is there a way to unproxy the injected bean A, so I could cast it to AImpl?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Try this:

if(AopUtils.isAopProxy(a) && a instanceof Advised) {
    Object target = ((Advised)a).getTargetSource().getTarget();
    AImpl ai = (AImpl)target;
}

Bonus: in Scala I am using the following equivalent function for the very same purpose:

def unwrapProxy(a: AnyRef) = a match {
    case advised: Advised if(AopUtils.isAopProxy(advised)) => 
                            advised.getTargetSource.getTarget
    case notProxy => notProxy
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...