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
How to Use a Custom Font in Java
Setting Jpg Compression Level with Imageio in Java
How to Count Frequency of Characters in a String
How to Define a Relative Path in Java
How to Create a Multidimensional Arraylist in Java
Executing Another Application from Java
Io Error: the Network Adapter Could Not Establish the Connection
How to Read File from End to Start (In Reverse Order) in Java
Why Do I Get the "Unhandled Exception Type Ioexception"
Rationale for Matcher Throwing Illegalstateexception When No 'Matching' Method Is Called
How to Split a Java String at Backslash
Simple Division in Java - Is This a Bug or a Feature
Convert Boolean to Int in Java
Are Java Static Initializers Thread Safe