Self Injection in Spring
Since Spring AOP is proxy based, only ‘external’ method calls coming in through the proxy will be intercepted. i.e. This means that ‘self-invocation’, i.e. a method within the target object calling some other method of the target object, won’t lead to an actual transaction at runtime even if the invoked method is marked with @Transactional.
Why @Autowired does not work
@Service public class UserService implements Service{ @Autowired private Service self; }
The above code throws a NoSuchBeanDefinitionException. Logically speaking @Autowired doesn’t work because the bean can’t be injected until it has been fully constructed. This means that Spring has to have injected all properties of the bean. Effectively the above code creates a circular dependency because Spring tries to instantiate the bean and when it does, it discovers that it needs to Autowire
another bean. When it tries to find that bean it can’t because the bean hasn’t been added to the list of initialized beans (because it’s currently being initialized).
Alternatives
Below are couple of approaches which work.
@Service(value = "someService") public class UserService implements Service{ @Resource(name = "someService") private Service self; }
or
@Service public class UserService implements Service { @Autowired private ApplicationContext applicationContext; private Service self; @PostConstruct private void init() { self = applicationContext.getBean(UserService); } }
Posted on May 26, 2011, in spring and tagged spring. Bookmark the permalink. Leave a comment.
Leave a comment
Comments 0