Spring Stereotype Annotations
March 13, 2023
This page will walk through Spring stereotype annotations. Stereotype annotations denote roles of types or methods at conceptual level. Stereotype annotations are @Component
, @Service
, @Repository
and @Controller
annotations. These annotations are used for auto-detection of beans using @ComponentScan
and component-scan
. The Spring stereotype @Component
is parent stereotype. The other stereotypes i.e @Service
, @Repository
and @Controller
are the specialization of @Component
annotation. The @ComponentScan
is used in java configuration and component-scan
is used for auto component scanning in XML. We need to provide base-package name in @ComponentScan
and component-scan
. Here we will describe the usability of stereotype annotations with complete example.
Contents
@Component
@Component
annotation is a stereotype and is used at class level that makes the class a component. These classes are eligible for auto-detection through classpath scanning. In java configuration, @ComponentScan
annotation is used to auto detect the component and in spring application context XML, component-scan
tag is used for auto-detection through classpath. @Component
annotation has a value attribute that is a component name and it will also be considered as spring bean name.
@Component public class BookUtility {}
@Service
@Service
annotation is a stereotype and is used at class level that makes the class a service. A service class can act as Business Service Facade of j2EE pattern. A service class implements business logic using DAO, utility classes etc. The classes annotated with @Service
are auto detected through classpath scanning. Annotating a class with @Service
gives a logical sense that these classes are services. If we use @Component
annotation on service class instead of @Service
, there is no harm but for better readability, a service class should be annotated with @Service
annotation. @Service
annotation is a specialization of @Component
annotation. @Service
annotation has the attribute as value which is the suggestion of component name as well as a spring bean name for that class.
@Service public class BookService {}
@Repository
@Repository
annotation is a stereotype and is used at class level. The class, whose behavior is to store, fetch or search data, comes to the repository category. These types of classes should be annotated with @Repository
annotation for auto-detection through classpath scanning. DAO classes should be annotated with @Repository
annotation for auto-detection. @Repository
annotation is the specialization of @Component
annotation. @Repository
annotation has an attribute value which is the suggestion of component name as well as spring bean name for that class.
@Repository public class BookDAO {}
@Controller
@Controller
annotation is a stereotype and is used at class level in spring MVC. It indicates that the class is a web controller. These classes annotated with @Controller
are auto detected through classpath scanning. @Controller
annotation is usually used in combination with @RequestMapping
annotation in spring MVC. @Controller
annotation is a specialization of @Component
annotation. @Controller
annotation has an attribute value which is the suggestion for component name and will also be used as spring bean name for that class.
@Controller @RequestMapping(value = "/book") public class BookController {}
@ComponentScan and component-scan
@ComponentScan
annotation is used at class level with @Configuration
. @ComponentScan
defines the component scanning directives. The attribute basePackages
of @ComponentScan
annotation defines the directives of components for auto scanning i.e base package name . In XML the parallel tag is component-scan
using which we define package name. The attribute annotation-config
of component-scan
is by default true and hence @Autowired
annotation is detected by default while using component-scan
in spring application context XML. Find Code snippet for @ComponentScan
.
@Configuration @ComponentScan("com.concretepage") @EnableWebMvc public class AppConfig extends WebMvcConfigurerAdapter {}
component-scan
.
<context:component-scan base-package="com.concretepage"/>
Complete Example
Find the complete example. The below class is using@Component
annotation.
BookUtility.java
package com.concretepage.utility; import org.springframework.stereotype.Component; @Component public class BookUtility { public int calculateArea(int length, int width) { return length * width; } }
@Service
annotation.
BookService.java
package com.concretepage.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.concretepage.dao.BookDAO; import com.concretepage.utility.BookUtility; import com.concretepage.vo.Book; @Service public class BookService { @Autowired private BookDAO bookDAO; @Autowired private BookUtility utility; public String largestAreaBookName() { int lgarea = 0; String bookName = ""; for (int i=0;i < 2;i++) { Book book = bookDAO.getBook(i); int area = utility.calculateArea(book.getLength(), book.getWidth()); if (lgarea < area) { lgarea = area; bookName = book.getBookName(); } } return bookName; } }
@Repository
annotation.
BookDAO.java
package com.concretepage.dao; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Repository; import com.concretepage.vo.Book; @Repository public class BookDAO { List<Book> bookList = new ArrayList<>(); { Book book1 = new Book(1, "Ramayana",5,4); Book book2 = new Book(2, "Mahabharat",6,3); bookList.add(book1); bookList.add(book2); } public Book getBook(int id) { //In real time, use database to fetch data return bookList.get(id); } }
@Controller
annotation.
BookController.java
package com.concretepage.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.concretepage.service.BookService; @Controller @RequestMapping(value = "/book") public class BookController { @Autowired private BookService service; @RequestMapping(value = "/service") public ModelAndView bookName(ModelAndView modelAndView) { modelAndView.addObject("bookName", service.largestAreaBookName()); modelAndView.setViewName("success"); return modelAndView; } }
@ComponentScan
annotation.
AppConfig.java
package com.concretepage.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @Configuration @ComponentScan("com.concretepage") @EnableWebMvc public class AppConfig extends WebMvcConfigurerAdapter { @Bean public InternalResourceViewResolver setupViewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/pages/"); resolver.setSuffix(".jsp"); resolver.setViewClass(JstlView.class); return resolver; } }
package com.concretepage.config; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRegistration.Dynamic; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; public class WebAppInitializer implements WebApplicationInitializer { public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(AppConfig.class); ctx.setServletContext(servletContext); Dynamic dynamic = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx)); dynamic.addMapping("/"); dynamic.setLoadOnStartup(1); } }
package com.concretepage.vo; public class Book { private int bookId; private String bookName; private int length; private int width; public Book(int bookId, String bookName, int length, int width) { this.bookId = bookId; this.bookName= bookName; this.length = length; this.width = width; } public int getBookId() { return bookId; } public String getBookName() { return bookName; } public int getLength() { return length; } public int getWidth() { return width; } }
<html> <head><title>Spring 4</title></head> <body> ${bookName} </body> </html>
build.gradle
apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'war' archivesBaseName = 'spring4' version = '1' repositories { mavenCentral() } dependencies { compile 'org.springframework.boot:spring-boot-starter-web:1.2.7.RELEASE' compile 'javax.servlet:javax.servlet-api:3.1.0' compile 'jstl:jstl:1.2' providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat:1.2.7.RELEASE' }
Now I am done. Happy spring learning!