2

This is a question to understand spring internals. There are a couple of workarounds suggested for self injection of a bean in spring because @Autowired doesn't work. Here are few threads. I would like to know the reason why and how does self injection work technically with @Resource annotation?


@Service(value = "someService")
public class UserService implements Service{
   @Resource(name = "someService")
   private Service self;
}

Any links to the spring source code would be appreciated. Thanks.

Community
  • 1
  • 1
Andy Dufresne
  • 6,022
  • 7
  • 63
  • 113
  • Why would you want to do such a hideous thing in the first place? – Sean Patrick Floyd May 21 '11 at 11:14
  • To make Spring AOP intercept internal method calls. Shifting to AspectJ just for this reason does not seem to be practical. – Andy Dufresne May 22 '11 at 04:42
  • if you need this then you shouldn't use proxy based approach and it's really not about shifting but to choose the right thing for the need than trying to find horrendous workarounds.Even Spring [docs](http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-understanding-aop-proxies) also suggests if you're using Spring AOP then you should not use self-invocation else look to AspectJ since it doesn't have self invocation issue. – Premraj May 24 '11 at 07:28
  • @Falcon: But sometimes it's excessively awkward to avoid a self-invocation (e.g., because AOP support is being retrofitted onto an existing complex app) and the AspectJ weaver can interact poorly with some environments. – Donal Fellows May 24 '11 at 14:38
  • Also at times an application needs this self injection feature only at few places. Hence there is not much of a need to shift to AspectJ. AspectJ has its own set of features like compile time weaving, various more joinpoints then Spring AOP which could be used only if there is an actual need :) – Andy Dufresne May 24 '11 at 16:17
  • @Donal, @Amit - yes.. but if Spring itself says it should be avoided and there is no better solution from Spring at this moment.. what you will do? – Premraj May 24 '11 at 17:56

2 Answers2

2

From another thread I got a response which seems fairly ok. Basically it states that spring specially adds defensive checks for handling @Autowired beans but @Resource beans bypass it and hence it works.

Community
  • 1
  • 1
Andy Dufresne
  • 6,022
  • 7
  • 63
  • 113
0

I don't know how exactly spring handles it, but here are a few options (the CDI specification uses these for example):

  • incomplete instances. When beans are instantiated and put in the context, their status is set as 'incomplete' - that is, their instance exists but their dependencies are not injected. Thus, first beans are instantiated, put in the context, and on the next stage their dependencies are injected. This makes the above case trivial - the container first create the instance and then, for each injection point, gets the desired bean from the context - itself, in this case

  • proxies. A proxy is created for each bean, so that it has beans without actually having instantiated the beans. It creates the proxies (by interface/concrete class), injects them into one another, and passes proxies around when needed. Finally each proxy gets its actual bean. This is perhaps not the case above, because this is used by CDI to handle circular constructor injection.

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • 1
    The intent behind this question is to understand why @Resource works and @Autowired doesn't. The reason why @Autowired does not work is explained in the one of the linked threads in my question. I want to understand why @Resource works - basically understand how does Spring handle @Resource separately then @Autowired since both seem to do the same job - inject the dependencies – Andy Dufresne May 21 '11 at 16:24