AOP Proxy Classes in Spring and @Autowire

Posted by Tejus Parikh on January 5, 2012

This is an issue that gets me once every blue moon. Lets say that I have two classes DependencyClass and MainClass:

@Transactional
@Service
class DependencyClass implements IDependencyClass {
	
}

class MainClass {
    @Autowired
    private IDependencyClass insert;
}

DependencyClass makes use of Spring's @Transactional support, which is provided through AOP Proxies. This code works when I fire it up. However, if I add another implementation, and want to change the code to the following:

@Transactional
@Service
class DependencyClass implements IDependencyClass {
	
}

@Transactional
@Service
class DependencyClassAlternate implements IDependencyClass {
    
}

class MainClass {
    @Autowired
    private DependencyClass dc;

    @Autowired
    private DependencyClassAlternate dca;
}

I get this nasty on the application startup:

NoSuchBeanDefinitionException: No matching bean of type [DependencyClass] found for dependency

The reason for this is simple. Within the Spring container, the concrete class DependencyClass has been replaced by a proxy. Therefore, as far as the system is concerned, there is no matching bean of type DependencyClass.

Inevitably, when this occurs, I spend too much time looking to other issues with my application context setup. However, the solution is easy and straightforward, once you realize what the problem is:

@Transactional
@Service("dc")
class DependencyClass implements IDependencyClass {
	
}

@Transactional
@Service("dca")
class DependencyClassAlternate implements IDependencyClass {
    
}

class MainClass {
    @Autowired
    @Qualifier("dc")
    private IDependencyClass dc;

    @Autowired
    @Qualifier("dca")
    private IDependencyClass dca;
}

Basically, one needs to change the type back to an interface, then use named services and the @Qualifer annotation to inject the desired dependency.

Related Posts:

Tejus Parikh

Tejus is an software developer, now working at large companies. Find out when I write new posts on twitter, via RSS or subscribe to the newsletter: