The scope of the Bean

In Spring, the bodies that make up the application and the objects managed by the Spring IoC container are called beans. Simply put, beans are objects that are initialized, assembled, and managed by the IoC container

The Request and Session scopes are only used in Web-based applications (regardless of which Web application framework you are using), and only in web-based Spring ApplicationContext.

Singleton (Singleton)

When a bean is scoped to a Singleton, there will be only one shared bean instance in the Spring IoC container, and all requests for the bean will return only the same instance of the bean as long as the ID matches the bean definition. A Singleton is a Singleton type that automatically creates a bean object when the container is created. It exists regardless of whether you use it or not, and the object you get is the same object each time. Note that the Singleton scope is the default scope in Spring. To define a bean as a singleton in XML, configure it as follows:

<bean id="ServiceImpl" class="cn.csdn.service.ServiceImpl" scope="singleton">
Copy the code

Testing:

@Test
 public void test03(){
     ApplicationContext context = newClassPathXmlApplicationContext("applicationContext.xml");
     User user = (User) context.getBean("user");
     User user2 = (User) context.getBean("user");
     System.out.println(user==user2);
 }
Copy the code

Prototype

When a bean is scoped to Prototype, a bean definition corresponds to multiple object instances. A prototype-scoped bean results in a new bean instance being created each time the bean is requested (injected into another bean, or programmatically called on the container’s getBean() method). Prototype is the Prototype type, which is not instantiated when we create the container. Instead, we create an object when we get the bean, and we get a different object each time. As a rule of thumb, you should use the Prototype scope for stateful beans and the Singleton scope for stateless beans. Defining the bean as prototype in XML can be configured as follows:

<bean id="account" class="com.foo.DefaultAccount" scope="prototype"/> class="com.foo.DefaultAccount" singleton="false"/>Copy the code

Request

When the scope of a bean is Request, it means that in an HTTP Request, one bean definition corresponds to one instance. That is, each HTTP request has its own bean instance, which is created from a bean definition. This scope is valid only in the case of web-based Spring ApplicationContext. Consider the following bean definition:

<bean id="loginAction" class="cn.csdn.LoginAction" scope="request"/>
Copy the code

For each HTTP request, the Spring container will create a new loginAction bean instance based on the loginAction bean definition, which is valid only within the current HTTP Request. Therefore, you can safely change the internal state of the instance you build as needed, while instances created based on the loginAction bean definition in other requests will not see these request-specific state changes. When the processing of the request ends, the request scoped bean instance is destroyed.

Session

When the scope of a bean is Session, it means that in an HTTP Session, one bean definition corresponds to one instance. This scope is valid only in the case of web-based Spring ApplicationContext. Consider the following bean definition:

 <bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
Copy the code

For an HTTP Session, the Spring container creates a brand new userPreferences Bean instance based on the userPreferences Bean definition, And the userPreferences Bean is only valid for the current HTTP Session. As with the Request scope, you can safely change the internal state of the instance you create as needed, whereas other HTTP Session instances created under userPreferences will not see these session-specific state changes. When an HTTP Session is finally discarded, the beans scoped by that HTTP Session are also discarded.

Global Session

When a bean is scoped to a Global Session, one bean definition corresponds to one instance in a Global HTTP Session. Typically, this is valid only when the portlet context is used. This scope is valid only in the case of web-based Spring ApplicationContext. Consider the following bean definition:

<bean id="user" class="com.foo.Preferences "scope="globalSession"/>
Copy the code

The Global Session scope is similar to the standard HTTP Session scope, but only makes sense in portlet-based Web applications. The Portlet specification defines the concept of a global Session, which is shared by all the different portlets that make up a Portlet Web application. Beans defined in the Global Session scope are limited to the lifecycle of the global Portlet session.

The life cycle of the Bean

For ordinary Java objects, the life cycle is relatively simple: objects are created when new and collected by the garbage collection mechanism when there are no references.

Objects hosted by the Spring Ioc container, on the other hand, have their life cycles completely controlled by the container. As shown below.

Instantiate the Bean

The Bean is instantiated depending on whether it is BeanFactory or ApplicationContext.

BeanFactory: creatBean is called when an uninitialized bean is requested from the container, or when the bean needs to be injected into another uninitialized dependency

2.ApplicationContext container, which instantiates all beans after the container is started.

3. The container instantiates by getting information from the BeanDefinition object. And this step is just a simple instantiation without dependency injection

4. The instantiation object is wrapped in a BeanWrapper object, which provides an interface to set the properties of the object, avoiding the need for reflection to set the properties

Setting object properties (dependency injection)

The instantiated object is wrapped in a BeanWrapper object and is still in its native state without dependency injection

Spring then does dependency injection based on the information in BeanDefinition and through the interface provided by BeanWrapper to set properties

Injecting the Aware interface

Spring then detects whether the object implements the xxxAware interface and injects the associated instance into the bean.

At this point the bean object has been constructed correctly.

BeanNameAware

If the bean implements this interface, Spring passes the bean’s ID to the setBeanName() method

BeanFactoryAware

If the bean implements this interface, Spring calls the setBeanFactory method, passing in the BeanFactory instance

ApplicationContextAware

If this interface is implemented, its setApplicationContext() method is called, passing a reference to the application context into the bean;

BeanPostProcessor

This interface provides two functions to do some custom processing on the object before it is used. At this point, the Bean is passed in, and you can do any processing on the Bean.

Pre-processing: Bean instance creation

1.postProcessBeforeInitialzation( Object bean, String beanName )

2. Will be executed prior to the InitialzationBean, where all Aware interface injection is done

Post processing:

1. PostProcessAfterInitialzation (Object beans, String beanName)

InitializingBean and init – method

This phase is entered when the current processing is complete.

afterPropertiesSet()

This stage can also add our custom logic before the bean is formally constructed. There is no way to deal with the object itself at this stage, only to add some additional logic.

To use it, we need to have the bean implement the interface and write the added logic in the function. Spring then checks if the current bean implements the interface after the pre-processing is complete and executes the afterPropertiesSet function.

Of course, Spring, to make it less intrusive to the client code, provides the bean configuration with the init-method property, which specifies the name of the function that needs to be executed at this stage. Spring executes the function we set up during initialization. Init-method essentially still uses the InitializingBean interface.

DisposableBean and destroy – method

As with init-method, you can execute the specified logic before the bean is destroyed by specifying a function for destroy-method.