@Named annotation in Spring MVC
annotations, java, jsr330, spring-mvc
Solution
`@Named` works the same as `@Component`. However, the annotations `@Controller`, `@Service`, and `@Repository` are more specific.
From the Spring docs:
`@Component` is a generic stereotype for any Spring-managed component. `@Repository`, `@Service`, and `@Controller` are specializations of `@Component` for more specific use cases, for example, in the persistence, service, and presentation layers, respectively.
For example, these stereotype annotations make ideal targets for pointcuts. It is also possible that `@Repository`, `@Service`, and `@Controller` may carry additional semantics in future releases of the Spring Framework. Thus, if you are choosing between using `@Component` or `@Service` for your service layer, `@Service` is clearly the better choice. Similarly, as stated above, `@Repository` is already supported as a marker for automatic exception translation in your persistence layer.
This section explains the difference with `@Named`.
Many components, like Spring's `DispatcherServlet` (MVC configuration in `WebApplicationContext`) aren't looking for `Component`, they are looking for `@Controller`. So when it scans your class, it won't find it in `@Named`. In a similar fashion, transaction management with `@Transactional` looks for `@Service` and `@Repository`, not for the more generic `@Component`.
Problem
Per Spring 3 document, The IoC container, the `@Named` annotation is a standard equivalent to the `@Component` annotation. Since `@Repository`, `@Service`, and `@Controller` are all `@Component`, I tried to used `@Named` for all of them in my Spring MVC application. It works fine. But I found the replacement of `@Controller` seems to have a bug. In the controller class, originally, it was ``` @Controller public class MyController{ ... } ``` It works fine. When I changed `@Controller` to `@Named` ``` @Named public class MyController{ ... } ``` It failed with error: "No mapping found for HTTP request with URI ...". But if I added `@RequestMapping` to the class as follow ``` @Named @RequestMapping public class MyController{ ... } ``` It would work as expected. For `@Repository` and `@Service`, I can simply replace them with `@Named` with no issue. But the replacement of `@Controller` needs extra work. Is there anything I am missing in the configuration?