Announcement Announcement Module
Collapse
No announcement yet.
JdkDynamicAopProxy, where's my object? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • JdkDynamicAopProxy, where's my object?

    I'm having trouble getting a bean from my context and using it now that I'm trying to add in AOP, code is described below, more details about my problem are at the very bottom of this message.

    I have defined an aspect using annotations that looks something like this:

    Code:
    @Aspect
    public class MyAspect {
        @Before("foo()")
        public void handleBefore() {
              System.out.println("handleBefore invoked on MyAspect");
        }
       
        @Pointcut("execution(* com.acme.foo.MyDomainObject.*(..))")
        public void foo() {}
    }
    In my application context I am defining an instance of "MyDomainObject" and setting up the AOP stuff:

    Code:
    ...
    	<aop:aspectj-autoproxy>
    		<aop:include name="myAspect"/>
    	</aop:aspectj-autoproxy>
    
    	<bean id="myAspect"
    		class="com.acme.aspects.MyAspect" />
    
           <bean id="myObject" class="com.acme.foo.MyDomainObject" />
    ...
    Now my unit test looks like this:

    Code:
    public class MyAspectTest extends AbstractDependencyInjectionSpringContextTests {
    
    	/* (non-Javadoc)
    	 * @see org.springframework.test.AbstractSingleSpringContextTests#getConfigLocations()
    	 */
    	@Override
    	protected String[] getConfigLocations() {
    		return new String[] {"classpath:/com/acme/test/aspects/aspects-test-config.xml"};
    	}
    
    	@Test
    	public void testAspect() {
    		Object tmp = getApplicationContext().getBean("myObject");
                    MyDomainObject mdo = (MyDomainObject) tmp;
                    mdo.sayHello();
    	}
    The problem I have is when I get the bean from the context and store it in "tmp", it shows up in the debugger as a JdkDynamicAopProxy, when I try to cast it to a MyDomainObject it fails with a ClassCastException.

    Am I missing something??

  • #2
    So basically I went back to the Spring AOP reference and read this:

    Spring AOP defaults to using standard J2SE dynamic proxies for AOP proxies. This enables any interface (or set of interfaces) to be proxied.
    Source: http://static.springframework.org/sp...uction-proxies

    I realized that "MyDomainObject" was a concrete class that did not implement an interface with the methods I was invoking. So I had to go back and make an IMyDomainObject interface which has a "public void sayHello();" method.

    All is well now.

    I will mention (in case someone can't/doesn't want to go the interface approach) Spring can proxy concrete types by using CGLIB, refer to the link provided above.

    Comment


    • #3
      So basically here is what I reazlied.

      Spring will proxy classes which do not implement any interface by using CGLIB, however, if you do implement an interface Spring AOP can only pick up on methods defined in that interface.

      Basically, I had an interface that was just a marker (i.e. no methods in it) that my class implemented...Spring AOP never detected calls to methods on the concrete class that implemented the marker interface (makes sense to me, but I didn't realize it at first).

      hope all this helps.

      Comment


      • #4
        One think to add is that you can also force spring to use cglib
        Code:
        <aop:aspectj-autoproxy proxy-target-class="true"/>

        Comment


        • #5
          what if I wanted my concrete class to implement the Spring BeanFactoryAware interface...how can I get Spring AOP to still pick up my concrete class?

          Comment

          Working...
          X