History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: IDEADEV-21566
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Normal Normal
Assignee: Peter Gromov
Reporter: Taras Tielkes
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
IDEA: Development

spring + aop: target method matching should be aware of proxy type

Created: 24 Sep 07 17:11   Updated: 06 Dec 07 18:51
Component/s: J2EE.Spring
Fix Version/s: Selena 7.0.2

Original Estimate: Unknown Remaining Estimate: Unknown Time Spent: Unknown

Build: 7,294
Fixed in build: 7,513


 Description  « Hide
Spring AOP has two proxying modes:
  • "default" (JDK interface proxy if possible, fallback to CGLIB subclass proxy if not)
    • when the target bean class implements one or more interfaces, a JDK dynamic proxy is created, intercepting calls only to methods defined on the interface(s).
    • when the target bean class does not implement any interfaces, a CGLIB subclass proxy is created, intercepting calls to all class methods
  • "forced-cglib"
    • If any of the elements (<tx:annotation-driven>, <aop:config>, <aop:aspectj-autoproxy>) present in the current ApplicationContext has a proxy-target-class="true" attribute, CGLIB subclass proxies will be forced for all advised beans. IDEA should look in the current fileset (but not the parent fileset) to see if an element forcing proxy-target-class is present.

Observed behavior: IDEA seems to match all methods from the bean class.

It would be nice if the proxy type for a given bean was part of the AOP model: I think it can affect evaluation of this() pointcut designator.



 All   Comments   Work Log   Change History      Sort Order:
Taras Tielkes - 27 Sep 07 02:16
Here are some tests/examples. Note that identical logic applies to advice from <aop:aspectj-autoproxy/> and <tx:annotation-driven/>.
I'll create a separate issue for this() details.
public interface TargetInterface {
  void interfaceMethod();
}
public class TargetClassNoInterface {
  public void classMethod() {}
}
public class TargetClassWithInterface implements TargetInterface {
  public void interfaceMethod() {}
  public void classMethod() {}
}
<!-- interface present, JDK interface proxy, should match "interfaceMethod" only -->
<bean id="target" class="foo.bar.aop.testcase.TargetClassWithInterface"/>                                                
<aop:config>                                                                                                 
  <aop:aspect ref="simpleAspectBean">                                                                        
    <aop:around method="before" pointcut="execution(* foo.bar.aop.testcase.*.*(..))"/>
  </aop:aspect>                                                                                              
</aop:config>
<!-- no interfaces, CGLIB proxy, should match both methods -->
<bean id="target" class="foo.bar.aop.testcase.TargetClassNoInterface"/>                                                
<aop:config>                                                                                                 
  <aop:aspect ref="simpleAspectBean">                                                                        
    <aop:around method="before" pointcut="execution(* foo.bar.aop.testcase.*.*(..))"/>
  </aop:aspect>                                                                                              
</aop:config>
<!-- no interfaces, CGLIB proxy (no other choice), should match both methods -->
<bean id="target" class="foo.bar.aop.testcase.TargetClassNoInterface"/>                                                
<aop:config proxy-target-class="false">                                                                                                 
  <aop:aspect ref="simpleAspectBean">                                                                        
    <aop:around method="before" pointcut="execution(* foo.bar.aop.testcase.*.*(..))"/>
  </aop:aspect>                                                                                              
</aop:config>
<!-- has interface, but forced CGLIB proxy, should match both methods -->
<bean id="target" class="foo.bar.aop.testcase.TargetClassWithInterface"/>                                                
<aop:config proxy-target-class="true">                                                                                                 
  <aop:aspect ref="simpleAspectBean">                                                                        
    <aop:around method="before" pointcut="execution(* foo.bar.aop.testcase.*.*(..))"/>
  </aop:aspect>                                                                                              
</aop:config>
<!-- has interface, but forced (by other element) CGLIB proxy, should match both methods -->
<bean id="target" class="foo.bar.aop.testcase.TargetClassWithInterface"/>                                                
<tx:annotation-driven proxy-target-class="true"/>
<aop:config>                                                                                                 
  <aop:aspect ref="simpleAspectBean">                                                                        
    <aop:around method="before" pointcut="execution(* foo.bar.aop.testcase.*.*(..))"/>
  </aop:aspect>                                                                                              
</aop:config>
<!-- has interface, but forced (by other element, "true" overrides "false") CGLIB proxy, should match both methods -->
<bean id="target" class="foo.bar.aop.testcase.TargetClassWithInterface"/>                                                
<aop:aspectj-autoproxy proxy-target-class="true"/>
<aop:config proxy-target-class="false">                                                                                                 
  <aop:aspect ref="simpleAspectBean">                                                                        
    <aop:around method="before" pointcut="execution(* foo.bar.aop.testcase.*.*(..))"/>
  </aop:aspect>                                                                                              
</aop:config>