views:

53

answers:

3

According to the Spring docs, to enable autodetection of annotated controllers, you add component scanning to your configuration:

<context:component-scan base-package="org.springframework.samples.petclinic.web"/>

My question is, why is this necessary?

If a Controller has an annotation to already indicate what it is, shouldn't that be enough for Spring without component scanning?

+4  A: 

How else would Spring find the classes? If you haven't told Spring to look in a certain class or package, those classes aren't going to get loaded, and Spring is never going to find them.

This is more a limitation of the java classloading model (if you can call it a limitation), then it is a limitation of Spring.

skaffman
This is not really correct.There is no limitation, neither from the classloading model nor from spring.The base-package attribute is optional, spring would find the classes without that attribute. It could even find the classes without the configuration tag.The purpose is optimalization: if you only had the annotation, the framework had to load all the classes to check if the annotation is present what would be a significant overhead.
davyM
@davyM: Yes, and it does it with brute force, because the classloader provides no elegant way of informing Spring of what's available.
skaffman
@skaffman: that's true, at runtime you have to load a class before you can inspect it. But this does not provide an answer to the question of the TS: even when you specify the base package, the "limitation" that you describe is still there (you still have to "brute force" all the classes in that package), so that "limitation", or the fact that spring wouldn't know where to look for the classes is not an explanation as to why you have to put the "context:component-scan"-tag in your configuration.
davyM
+2  A: 

You only have to put the following in your configuration:

<context:annotation-config/>

If you only put the annotation on your class, the framework had to load all the classes to check if the annotation is present.

To minimize this overhead, you have to put the annotation-config tag in your configuration. That way the framework knows it has to check the classes from that configuration.

You can help the framework by specifying the package where your annotated classes are with the "base-package" attribute.

//EDIT//

This also explains the note in the documentation:

Note

<context:annotation-config/> only looks for annotations on beans in the same application context in which it is defined. This means that, if you put in a WebApplicationContext for a DispatcherServlet, it only checks for @Autowired beans in your controllers, and not your services.

davyM
+1  A: 

Simply annotating a class with @Controller doesn't necessarily mean you want it to be part of your Spring context. Imagine if the class is part of another application, or part of a third party library, or a deprecated component of your system, etc. Just because it is on the classpath doesn't necessarily mean that you want it automatically instantiated as a bean in your Spring context.

James Earl Douglas