@Scope – How to get Scope of Bean from Code
When we create a Bean we are creating actual instances of the class defined by that bean definition. We can also control the scope of the objects created from a particular bean definition.
There are 5 types of scopes in bean,
- singleton (default scope)
- prototype
- request
- session
- global-session
Singleton:
Single instance per spring IoC container
Prototype:
Single bean definition to any number of object instances.
Request:
Bean definition for each request. Only valid web-aware Spring ApplicationContext.
Session:
Bean definition for a session. Only valid web-aware Spring ApplicationContext.
Global-Session:
Similar to session but the only makes sense in the context of portlet-based web applications. Only valid web-aware Spring ApplicationContext.
In this example, we are going to see how can we get the Scope of bean through java code. We are going to create two bean classes – Employee and Student
Employee is Singleton and Student is Prototype.
Now let us see how to get these scope of bean through Java code.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>SpringBootScope</groupId> <artifactId>SpringBootScope</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>SpringBootScope</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.4.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Tomcat for JSP rendering --> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> </dependency> <!-- JSTL tag lib --> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>javax.servlet.jsp.jstl-api</artifactId> <version>1.2.1</version> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Employee.java
package com.javainfinite.model; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Scope(value = "singleton") @Component public class Employee { }
Student.java
package com.javainfinite.model; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Scope(value = "prototype") @Component public class Student { }
ScopeService.java
package com.javainfinite.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import com.javainfinite.model.Employee; import com.javainfinite.model.Student; @Service public class ScopeService { @Autowired Employee employee; @Autowired Student student; public Scope employeeScopeDisplay() { Scope scope = employee.getClass().getAnnotation(Scope.class); return scope; } public Scope studentScopeDisplay() { Scope scope = student.getClass().getAnnotation(Scope.class); return scope; } }
ScopeController.java
@Controller public class ScopeController { @Autowired ScopeService scopeService; @GetMapping(value = "/scope") public String beanScope(Model model) { Scope employeeScope = scopeService.employeeScopeDisplay(); Scope studentScope = scopeService.studentScopeDisplay(); model.addAttribute("employeeScope", employeeScope); model.addAttribute("studentScope", studentScope); return "home"; } }
App.java
package com.javainfinite; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; /** * Hello world! * */ @SpringBootApplication @ComponentScan("com.javainfinite") public class App { public static void main( String[] args ) { SpringApplication.run(App.class,args); } }
application.properties
spring.mvc.view.prefix = /WEB-INF/jsp/ spring.mvc.view.suffix = .jsp spring.mvc.static-path-pattern=/resources/**
home.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Home Page</title> </head> <body> <h3>Bean Scope for Employee and Student Bean </h3> <br> ${employeeScope } <br> ${studentScope } </body> </html>
From output we can see,
@org.springframework.context.annotation.Scope(proxyMode=DEFAULT, value=singleton, scopeName=)
scopeName and value are aliases, we cant mention both together.
If we try to mention both, we will get the exception
Example:
@Scope(value=”singleton”, scopeName=”ScopeName”)
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [com.javainfinite.App]; nested exception is org.springframework.core.annotation.AnnotationConfigurationException: In AnnotationAttributes for annotation [org.springframework.context.annotation.Scope] declared on class ‘com.javainfinite.model.Employee’, attribute ‘value’ and its alias ‘scopeName’ are declared with values of [singleton] and [ScopeName], but only one is permitted.
But we can use either one @Scope(value=”singleton”) or @Scope(scopeName=”singleton”)
Download code here