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
?
Proxying means that your client code thinks it's talking to one bean, but a proxy is really doing the listening and responding. This has been true since early distributed client/server computing models like CORBA.
The Proxy pattern uses a proxy (surrogate) object “in place of” another object. The objective of a proxy object is to control the creation of and access to the real object it represents.
Spring used two types of proxy strategy one is JDK dynamic proxy and other one is CGLIB proxy.
JDK Dynamic Proxies and CGLIB. Proxies in Spring are an implementation of the Proxy design pattern and help facilitate the paradigm of Aspect-Oriented Programming. Can inject additional functionality when an object is accessed such as logging, caching, transaction management, etc.
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 }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With