Self Injection with Spring

Self injection with Spring

Update: February 2016

Self autowiring will be officially supported in Spring Framework 4.3. The implementation can be seen in this GitHub commit.


The definitive reason that you cannot autowire yourself is that the implementation of Spring's DefaultListableBeanFactory.findAutowireCandidates(String, Class, DependencyDescriptor) method explicitly excludes the possibility. This is visible in the following code excerpt from this method:

for (String candidateName : candidateNames) {
if (!candidateName.equals(beanName) && isAutowireCandidate(candidateName, descriptor)) {
result.put(candidateName, getBean(candidateName));
}
}

FYI: the name of the bean (i.e., the bean that's trying to autowire itself) is beanName. That bean is in fact an autowire candidate, but the above if-condition returns false (since candidateName in fact equals the beanName). Thus you simply cannot autowire a bean with itself (at least not as of Spring 3.1 M1).

Now as for whether or not this is intended behavior semantically speaking, that's another question. ;)

I'll ask Juergen and see what he has to say.

Regards,

Sam (Core Spring Committer)

p.s. I've opened a Spring JIRA issue to consider supporting self-autowiring by type using @Autowired. Feel free to watch or vote for this issue here: https://jira.springsource.org/browse/SPR-8450

Spring self injection for transactions

It is totally ok.
Moreover there was a Jira ticket for supporting this feature using @Autowired annotations. It's fixed in Spring 4.3+ versions. However for xml-based configuration or using @Resource annotation it's working in the earlier versions.

You can see the discussion bellow this ticket. @Transactional is one of the use case for this:

Particularly interested in @Async and @Transactional use cases.

Does spring bean self injection works in new spring versions?

Ok I found the answer:
With Spring 4 it's possible to Self autowired

@Service
@Transactional
public class UserServiceImpl implements UserService{
@Autowired
private UserRepository repository;

@Autowired
private UserService userService;

@Override
public void update(int id){
repository.findOne(id).setName("ddd");
}

@Override
public void save(Users user) {
repository.save(user);
userService.update(1);
}
}

Can I inject same class using Spring?

This works fine -

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

How to inject dependencies into a self-instantiated object in Spring?

You can do this using the autowireBean() method of AutowireCapableBeanFactory. You pass it an arbitrary object, and Spring will treat it like something it created itself, and will apply the various autowiring bits and pieces.

To get hold of the AutowireCapableBeanFactory, just autowire that:

private @Autowired AutowireCapableBeanFactory beanFactory;

public void doStuff() {
MyBean obj = new MyBean();
beanFactory.autowireBean(obj);
// obj will now have its dependencies autowired.
}


Related Topics



Leave a reply



Submit