JavaBeans vs Spring beans vs POJOs
JavaBeans:At a basic level, JavaBeans are simply Java classes which adhere to certain coding conventions. Specifically, classes that
- 1) have
public
default (no argument) constructors- 2) allow access to their properties using accessor (getter and setter) methods
- 3) implement
java.io.Serializable
Spring Beans:
A Spring bean is basically an object managed by Spring. More specifically, it is an object that is instantiated, configured and otherwise managed by a Spring Framework container. Spring beans are defined in Spring configuration files (or, more recently, with annotations), instantiated by Spring containers, and then injected into applications.
Note that Spring beans need not always be JavaBeans. Spring beans might not implement the java.io.Serializable
interface, can have arguments in their constructors, etc.
This is the very basic difference between JavaBeans and Spring beans.
For more information, refer to the source of the above text, Shaun Abram's article JavaBeans vs Spring beans vs POJOs.
Spring Beans More (V.V.V):
@Bean
and @Autowired
do two very different things. The other answers here explain in a little more detail, but at a simpler level:
@Bean
tells Spring 'here is an instance of this class, please keep hold of it and give it back to me when I ask'.@Autowired
says 'please give me an instance of this class, for example, one that I created with an@Bean
annotation earlier'.
Does that make sense? In your first example, you're asking Spring to give you an instance of BookingService
, but you're never creating one, so Spring has nothing to give you. In your second example, you're creating a new instance of BookingService
, telling Spring about it, and then, in the main()
method, asking for it back.
If you wanted, you could remove the two additional lines from the second main()
method, and combine your two examples as below:
@SpringBootApplication
public class Application {
@Autowired
BookingService bookingService;
@Bean
BookingService bookingService() {
return new BookingService();
}
public static void main(String[] args) {
bookingService.book("Alice", "Bob", "Carol");
}
}
In this case, the @Bean
annotation gives Spring the BookingService
, and the @Autowired
makes use of it.
This would be a slightly pointless example, as you're using it all in the same class, but it becomes useful if you have the @Bean
defined in one class, and the @Autowired
in a different one.
Spring Bean Scopes Type
ApplicationContext
. singleton
and prototype
scopes are available in any type of IOC containers.Table of Contents 1. Spring Bean Scope Types 1.1. singleton scope 1.2. prototype scope 1.3. request scope 1.4. session scope 1.5. application scope 1.6. websocket scope 2. Custom thread scope 3. Summary
SCOPE | DESCRIPTION |
---|---|
singleton (default) | Single bean object instance per spring IoC container |
prototype | Opposite to singleton, it produces a new instance each and every time a bean is requested. |
request | A single instance will be created and available during complete lifecycle of an HTTP request.
Only valid in web-aware Spring
ApplicationContext . |
session | A single instance will be created and available during complete lifecycle of an HTTP Session.
Only valid in web-aware Spring
ApplicationContext . |
application | A single instance will be created and available during complete lifecycle of ServletContext .
Only valid in web-aware Spring
ApplicationContext . |
websocket | A single instance will be created and available during complete lifecycle of WebSocket .
Only valid in web-aware Spring
ApplicationContext . |
1.1. singleton scope
singleton
is default bean scope in spring container. It tells the container to create and manage only one instance of bean class, per container. This single instance is stored in a cache of such singleton beans, and all subsequent requests and references for that named bean return the cached instance.@Component //This statement is redundant - singleton is default scope @Scope ( "singleton" ) //This statement is redundant public class BeanClass { } |
<!-- To specify singleton scope is redundant --> < bean id = "beanId" class = "com.howtodoinjava.BeanClass" scope = "singleton" /> //or < bean id = "beanId" class = "com.howtodoinjava.BeanClass" /> |
1.2. prototype scope
prototype
scope results in the creation of a new bean instance every time a request for the bean is made by application code.prototype
scoped beans, only initialization callback methods are called. So as developer, you are responsible for clean up prototype-scoped bean instances and any resource there hold.@Component @Scope ( "prototype" ) public class BeanClass { } |
< bean id = "beanId" class = "com.howtodoinjava.BeanClass" scope = "prototype" /> |
prototype
scope for all stateful beans and the singleton
scope for stateless beans.RequestContextListener
or RequestContextFilter
.1.3. request scope
request
scope, container creates a new instance for each and every HTTP request. So, if server is currently handling 50 requests, then container can have at most 50 individual instances of bean class. Any state change to one instance, will not be visible to other instances. These instances are destructed as soon as the request is completed.@Component @Scope ( "request" ) public class BeanClass { } //or @Component @RequestScope public class BeanClass { } |
< bean id = "beanId" class = "com.howtodoinjava.BeanClass" scope = "request" /> |
Read More: How web servers work?
1.4. session scope
session
scope, container creates a new instance for each and every HTTP session. So, if server has 20 active sessions, then container can have at most 20 individual instances of bean class. All HTTP requests within single session lifetime will have access to same single bean instance in that session scope.@Component @Scope ( "session" ) public class BeanClass { } //or @Component @SessionScope public class BeanClass { } |
< bean id = "beanId" class = "com.howtodoinjava.BeanClass" scope = "session" /> |
1.5. application scope
application
scope, container creates one instance per web application runtime. It is almost similar to singleton
scope, with only two differences i.e.application
scoped bean is singleton perServletContext
, whereassingleton
scoped bean is singleton perApplicationContext
. Please note that there can be multiple application contexts for single application.application
scoped bean is visible as aServletContext
attribute.
@Component @Scope ( "application" ) public class BeanClass { } //or @Component @ApplicationScope public class BeanClass { } |
< bean id = "beanId" class = "com.howtodoinjava.BeanClass" scope = "application" /> |
1.6. websocket scope
@Component @Scope ( "websocket" ) public class BeanClass { } |
< bean id = "beanId" class = "com.howtodoinjava.BeanClass" scope = "websocket" /> |
websocket
scoped beans are typically singletons and live longer than any individual WebSocket session.2. Custom thread scope
thread
scope using class SimpleThreadScope
. To use this scope, you must use register it to container using CustomScopeConfigurer
class.< bean class = "org.springframework.beans.factory.config.CustomScopeConfigurer" > < property name = "scopes" > < map > < entry key = "thread" > < bean class = "org.springframework.context.support.SimpleThreadScope" /> </ entry > </ map > </ property > </ bean > |
@Component @Scope ( "thread" ) public class BeanClass { } |
< bean id = "beanId" class = "com.howtodoinjava.BeanClass" scope = "thread" /> |
3. Summary
In this quick tutorial, you'll learn about the different types of bean scopes in the Spring framework.
- singleton
- prototype
- request
- session
- application
- websocket
2. Singleton Scope
Defining a bean with singleton scope means the container creates a single instance of that bean, and all requests for that bean name will return the same object, which is cached. Any modifications to the object will be reflected in all references to the bean. This scope is the default value if no other scope is specified.
1
2
3
4
5
| public class Person { private String name; // standard constructor, getters and setters } |
1
2
3
4
5
| @Bean @Scope ( "singleton" ) public Person personSingleton() { return new Person(); } |
1
| @Scope (value = ConfigurableBeanFactory.SCOPE_SINGLETON) |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| private static final String NAME = "John Smith" ; @Test public void givenSingletonScope_whenSetName_thenEqualNames() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext( "scopes.xml" ); Person personSingletonA = (Person) applicationContext.getBean( "personSingleton" ); Person personSingletonB = (Person) applicationContext.getBean( "personSingleton" ); personSingletonA.setName(NAME); Assert.assertEquals(NAME, personSingletonB.getName()); ((AbstractApplicationContext) applicationContext).close(); } |
1
2
3
4
5
6
7
8
| <? xml version = "1.0" encoding = "UTF-8" ?> xsi:schemaLocation="http://www.springframework.org/schema/beans < bean id = "personSingleton" class = "org.baeldung.scopes.Person" scope = "singleton" /> </ beans > |
3. Prototype Scope
A bean with prototype scope will return a different instance every time it is requested from the container. It is defined by setting the value prototype to the @Scope annotation in the bean definition:
1
2
3
4
5
| @Bean @Scope ( "prototype" ) public Person personPrototype() { return new Person(); } |
1
| @Scope (value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| private static final String NAME = "John Smith" ; private static final String NAME_OTHER = "Anna Jones" ; @Test public void givenPrototypeScope_whenSetNames_thenDifferentNames() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext( "scopes.xml" ); Person personPrototypeA = (Person) applicationContext.getBean( "personPrototype" ); Person personPrototypeB = (Person) applicationContext.getBean( "personPrototype" ); personPrototypeA.setName(NAME); personPrototypeB.setName(NAME_OTHER); Assert.assertEquals(NAME, personPrototypeA.getName()); Assert.assertEquals(NAME_OTHER, personPrototypeB.getName()); ((AbstractApplicationContext) applicationContext).close(); } |
1
| < bean id = "personPrototype" class = "org.baeldung.scopes.Person" scope = "prototype" /> |
4. Web Aware Scopes
As mentioned, there are four additional scopes that are only available in a web-aware application context. These are less often used in practice.
1
2
3
4
5
| public class HelloMessageGenerator { private String message; // standard getter and setter } |
4.1. Request Scope
We can define the bean with request scope using the @Scope annotation:
1
2
3
4
5
| @Bean @Scope (value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) public HelloMessageGenerator requestScopedBean() { return new HelloMessageGenerator(); } |
1
2
3
4
5
| @Bean @RequestScope public HelloMessageGenerator requestScopedBean() { return new HelloMessageGenerator(); } |
1
2
3
4
5
6
7
8
9
10
11
12
13
| @Controller public class ScopesController { @Resource (name = "requestScopedBean" ) HelloMessageGenerator requestScopedBean; @RequestMapping ( "/scopes/request" ) public String getRequestScopeMessage( final Model model) { model.addAttribute( "previousMessage" , requestScopedBean.getMessage()); requestScopedBean.setMessage( "Good morning!" ); model.addAttribute( "currentMessage" , requestScopedBean.getMessage()); return "scopesExample" ; } } |
4.2. Session Scope
We can define the bean with session scope in a similar manner:
1
2
3
4
5
| @Bean @Scope (value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) public HelloMessageGenerator sessionScopedBean() { return new HelloMessageGenerator(); } |
1
2
3
4
5
| @Bean @SessionScope public HelloMessageGenerator sessionScopedBean() { return new HelloMessageGenerator(); } |
1
2
3
4
5
6
7
8
9
10
11
12
13
| @Controller public class ScopesController { @Resource (name = "sessionScopedBean" ) HelloMessageGenerator sessionScopedBean; @RequestMapping ( "/scopes/session" ) public String getSessionScopeMessage( final Model model) { model.addAttribute( "previousMessage" , sessionScopedBean.getMessage()); sessionScopedBean.setMessage( "Good afternoon!" ); model.addAttribute( "currentMessage" , sessionScopedBean.getMessage()); return "scopesExample" ; } } |
4.3. Application Scope
The application scope creates the bean instance for the lifecycle of a ServletContext.
1
2
3
4
5
6
| @Bean @Scope ( value = WebApplicationContext.SCOPE_APPLICATION, proxyMode = ScopedProxyMode.TARGET_CLASS) public HelloMessageGenerator applicationScopedBean() { return new HelloMessageGenerator(); } |
1
2
3
4
5
| @Bean @ApplicationScope public HelloMessageGenerator applicationScopedBean() { return new HelloMessageGenerator(); } |
1
2
3
4
5
6
7
8
9
10
11
12
13
| @Controller public class ScopesController { @Resource (name = "applicationScopedBean" ) HelloMessageGenerator applicationScopedBean; @RequestMapping ( "/scopes/application" ) public String getApplicationScopeMessage( final Model model) { model.addAttribute( "previousMessage" , applicationScopedBean.getMessage()); applicationScopedBean.setMessage( "Good afternoon!" ); model.addAttribute( "currentMessage" , applicationScopedBean.getMessage()); return "scopesExample" ; } } |
4.4. WebSocket Scope
Finally, let's create the bean with websocket scope:
1
2
3
4
5
| @Bean @Scope (scopeName = "websocket" , proxyMode = ScopedProxyMode.TARGET_CLASS) public HelloMessageGenerator websocketScopedBean() { return new HelloMessageGenerator(); } |
Comments
Post a Comment