Project
IntelliJ IDEA
Priority
Normal
Type
Bug
Fix versions
No Fix versions
State
Fixed
Assignee
Peter Gromov
Subsystem
J2EE.Spring
Affected versions
No Affected versions
Fixed in build
108.65  
  • Created by   Taras Tielkes
    4 years ago (24 Sep 2007 18:11)
  • Updated by   root
    2 years ago (17 Jan 2010 20:53)
  • Jira: IDEADEV-21566
    (history, comments)
 
IDEA-41149 spring + aop: target method matching should be aware of proxy type
0
Issue is visible to: All Users
  The issue is visible to the selected user group only
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.

Issue was resolved
Comments (1)
 
History
 
Linked Issues (?)
 
Taras Tielkes
  Taras Tielkes
27 Sep 2007 03:16
4 years ago
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>