spring-projects / spring-framework

Spring Framework
https://spring.io/projects/spring-framework
Apache License 2.0
56.47k stars 38.09k forks source link

toString() method is delegated to Interceptors and not to the Target [SPR-1553] #6251

Closed spring-projects-issues closed 12 years ago

spring-projects-issues commented 18 years ago

Tibor Hegyi opened SPR-1553 and commented

Hi,

The JavaDoc API for "org.springframework.aop.framework.AdvisedSupport.toProxyConfigString()" says that toString() is delegated to the target. Having looked at the source code of the method "org.springframework.aop.framework.JdkDynamicAopProxy.invoke()", I could see that the toString() method is delegated to the interceptor chain and not directly to the target. See below: // We need to create a method invocation... // invocation = advised.getMethodInvocationFactory().getMethodInvocation( // proxy, method, targetClass, target, args, chain, advised);

            invocation = new ReflectiveMethodInvocation(
                    proxy, target, method, args, targetClass, chain);

            // proceed to the joinpoint through the interceptor chain
            retVal = invocation.proceed(); // <----- HERE TOSTRING() GETS DELEGATED TO THE CHAIN

This is I think not correct as the Interceptors must be activated for the method of the proxy interfaces specified.

E.g. I have an interceptor that checks if a certain ThreadLocal variable is set if a method on a certain interface (the proxy interface) is called. If the variable is not set, it throws an RuntimeException.

I have received the proxy bean from the application context and wanted to log it, so I called its toString() method. This resulted in an exception thrown by my interceptor which was called on a method not part of the proxy interface.

I think toString() should be delegated to the target object in constrast to the interceptor chain as it is specified in the API Documentation.


Affects: 1.2.5

spring-projects-issues commented 18 years ago

Rob Harrop commented

This is the desired behavior. The call to toString() (defined on Object) will be taken by te JDK proxy and passed to the InvocationHandler. The IH will then pass the the call to the chain and finally on to the target. This is necessary when you realise that there may be no target so it is impractical to simply pass the call directly onto the target object.

Rob

spring-projects-issues commented 18 years ago

Tibor Hegyi commented

Hi Rob,

It may be "impractical" to call the Target directly but passing method calls to interceptors where the method is not part of any proxy interfaces to which the interceptors are linked is not too wise I think. This means that users would have to implement special logic in interceptors that are sensitive to toString() calls in scenarios where the interceptor normally cannot work. E.g. a custom Transactional or Security Interceptor is also called on toString()...

I still think, it is not the best way how it is handled.

Tibor