tags:

views:

2242

answers:

2

I have two Spring proxies set up:

  <bean id="simpleBean" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target">
        <ref local="simpleBeanTarget"/>
    </property>
    <property name="interceptorNames">
        <list>
            <value>cacheInterceptor</value>
        </list>
    </property>
</bean>   



 <bean id="springDao" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="springDaoTarget"/>
        <property name="interceptorNames">
            <list>
                <value>daoInterceptor</value>
            </list>
        </property>

    </bean>

simpleBean works just fine -- springDao does not.

The SpringDao class looks like:

public class SpringDao extends JdbcDaoSupport {

private SimpleJdbcTemplate simpleJdbcTemplate;

public SimpleJdbcTemplate getSimpleJdbcTemplate() {

 if (simpleJdbcTemplate==null) {
  simpleJdbcTemplate= new SimpleJdbcTemplate(getDataSource());
 }
 return simpleJdbcTemplate;
}
    ...

And I have my unit test autowired like this:

@Autowired
@Qualifier("springDao")
protected SpringDao springDao;

And the first indication something is wrong is I get this error:

Could not autowire field: . . . nested exception is java.lang.IllegalArgumentException

If I comment out the @Qualifier annotation and run my unit test again, I get this:

No unique bean of type ... expected single matching bean but found 2: [springDaoTarget, springDao]

That is what I expected.

So I changed my autowiring to

@Autowired
@Qualifier("springDaoTarget")
protected SpringCustomerCapacityDao springDao;

And added the following to my unit test:

     Object proxy = applicationContext.getBean("springDao");

 Assert.assertNotNull(proxy);
 Assert.assertTrue(proxy instanceof SpringDao);

And the instanceof test failed, which (to me) means that my proxy is not really my proxy.

So I'm confused. What's going on? How can I fix this?

Edit Here is the requested springDaoTarget definition, which will disappoint many people:

<bean id="springDaoTarget" class="com.company.SpringDao">

+1  A: 

It was easy to fix, once I figured it out. SpringDao no longer inherits from JdbcDaoSupport and now it works.

MikeHoss
+2  A: 

If the target of your proxy implements at least one interface then Spring's default behavior is to create a JDK Proxy that implements all the interfaces of the target. This means it will not be a subclass of the target class. You can override this by forcing the creation of CGLIB proxies instead which are dynamic subclasses of the target.

As a general rule, if you are going to use AOP but only use interfaces in a limited fashion you'll want to force CGLIB. Otherwise you will have lots of JDK Proxies in your container which are not of the same type as the bean implementations you loaded.

http://histos.typepad.com/blog/2006/12/spring_aop_cgli.html

cliff.meyers