Spring will certainly throw an exception if a necessary bean is
missing. Can it also throw an exception in the opposite scenario where
a bean is found but unnecessary?
TL/DR:
Spring does not support this (and probably never will).
Long version:
Detecting if a bean is used can be really hard.
First, lets define when does spring throw the "missing bean" exception.
During the initialisation of the spring context, spring creates the beans in the order in which it will allow for all dependencies to be satisfied (if possible). If a bean is missing a dependency, spring will throw an exception (as you said).
So, the exception is thrown during the spring context initialisation process.
Now, you could say that we could monitor this process and look for a bean that was not used as a dependency in any other bean.
The problem is that not all bean dependencies are defined during the spring context initialisation process.
Let's look at the following example:
First, we have a simple interface, DataService
public interface DataService {
String getData();
}
Now we have 2 spring beans that implement this interface:
@Service("firstDataService")
public class FirstDataService implements DataService {
@Override
public String getData() {
return "FIRST DATA SERVICE";
}
}
@Service("secondDataService")
public class SecondDataService implements DataService {
@Override
public String getData() {
return "SECOND DATA SERVICE";
}
}
Now, imagine that there is no bean that depends on these two beans directly. When I say directly, I mean there is no bean that depends on these beans via constructor-based
, setter-based
or field-based
dependency injection.
Because of that, spring will not inject these beans inside any other bean during the context initialisation process.
Now, consider the following bean:
@Service
public class DataCollector {
@Autowired
ApplicationContext applicationContext;
String getDataFromService(String beanName) {
DataService ds = (DataService) applicationContext.getBean(beanName);
return ds.getData();
}
}
If I call the getDataFromService
method of the DataCollector
bean with "firstDataService" value for the beanName
parameter, the method will return "FIRST DATA SERVICE" as a result.
If I call the method with "secondDataService", I will return "SECOND DATA SERVICE" as a result.
Now, when spring looks at the definition of DataController
during context initialisation, there is no way to determine on which beans DataCollector
depends on.
It all depends on the application logic, and the value that we use for the beanName
parameter when we call the getDataFromService
method.
Because of that, spring is not capable of determining if there is bean that is never used (because the bean usage can be dynamic, like in the case above).