4

I have a class say UserService which implements Service and annotated with Service StereoType, I'm using Spring AOP and want to do temporary workaround for this(I know this can be done in better way)

@Service
public class UserService implements Service{
   @Autowired
   private Service self;
}

I tried this but got BeanNotFoundException, did I missed anything?

I know I have to go with AspectJ with @Configurable but just looking for little temporary workaround

Community
  • 1
  • 1
Premraj
  • 7,802
  • 8
  • 45
  • 66

4 Answers4

6

Why on earth would you need to do this? In any method where you need to refer to the current instance, ie self you simply use the this keyword.

Are we missing something? If there's something else you're trying to do, try to clarify your question and we'll take a stab at it.

In case you're wondering, this 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 what you've done is created 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). Does that make sense? This is why you get the BeanNotFoundException because the bean can't be initialized.

Chris Thompson
  • 35,167
  • 12
  • 80
  • 109
  • 2
    @Chris-Thompson I understand but self-invocation will not work with Spring proxy based AOP approach, and I wanted a little workaround beside AOPContext.getCurrentProxy().. I know this doesn't work but wanted to know the reason – Premraj Feb 24 '11 at 16:45
  • I know I need to go with AspectJ with @Configurable but just looking for little temporary workaround – Premraj Feb 24 '11 at 16:48
  • 2
    @Premraj M Ah I understand. Based on my explanation, do you understand why it won't work? – Chris Thompson Feb 24 '11 at 16:52
  • @Chris: +1 for great explanation. However, given this constraint - how can one ever implement composites? Please can you explain? – Nilesh Feb 24 '11 at 17:35
  • @Nilesh, unfortunately that's not a concept I have a whole lot of experience with. Can you explain or perhaps post a question to that effect and reference this question? – Chris Thompson Feb 24 '11 at 17:40
  • @Chris Given this - If I have Class A autowired to B and B autowired A then also I should get BeanNotFoundException.. correct? – Premraj Feb 24 '11 at 18:32
  • @Premraj M Correct. To put it technically, I believe that the dependencies must form a directed, acyclic graph. – Chris Thompson Feb 24 '11 at 18:40
1

You can edit your class to be

@Service
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON, proxyMode = ScopedProxyMode.INTERFACES)
public class UserService implements Service
{
    @Autowired
    private Service self;
}

this should work

Jonathan Viccary
  • 722
  • 1
  • 9
  • 27
0

I know this isn't quite answering the question, but I'd suggest re-writing your code so that you do not need to rely on aspects being applied to the self-invocation. For example, if you have some transactional method, just make sure that the transaction stuff gets properly setup in the calling method.

If you really need to, you could make your class ApplicationContextAware and fetch the bean-with-aspects from the context

James Kingsbery
  • 7,298
  • 2
  • 38
  • 67
0

This works fine -

@Service(value = "someService")
public class UserService implements Service{
   @Resource(name = "someService")
   private Service self;
}
Premraj
  • 7,802
  • 8
  • 45
  • 66
  • @Amit - here is the reason http://stackoverflow.com/questions/5152686/self-injection-with-spring – Premraj May 21 '11 at 14:11