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);
    }
}
Advertisement

Posted on May 26, 2011, in spring and tagged . Bookmark the permalink. Leave a comment.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: