When you create abean
When defining, you can create a template (recipe) throughbean
Define the class definition to create a real instance.bean
The concept of definition as a recipe is important because it means that, just like using classes, you can create multiple object instances from a single recipe.
You can not only control to insert from specificbean
Define the various dependencies and configuration values in the created object, and you can also control thebean
Defines the scope of the created object. This method is very useful and flexible, because you can choose the scope of the object created by configuration without having to consider the scope of the object at the Java class level.bean
Ability to define deployment to one or more scopes.Spring
The framework supports six scopes, and four are used onlyweb
Environmental Science. You can create custom scopes.
The following table describes the scope of the support:
Scope | Description |
---|---|
singleton | (default) limits the scope of a single bean definition for each spring IOC container to a single object instance. |
prototype | Limits the scope of a single bean definition to any number of object instances |
request | Limits the scope of a single bean definition to the life cycle of a single HTTP request. That is, each HTTP request has a bean instance created. Only valid in spring ApplicationContext web container |
session | Limit the scope of a single bean definition to the HTTP session lifecycle. Only valid in spring ApplicationContext web container |
application | Limit the scope of a single bean definition to the ServletContext lifecycle. Only valid in spring ApplicationContext web container |
websocket | Limit a single bean definition to the websocket lifecycle. Only valid in spring ApplicationContext web container |
fromSpring3.0
After, the thread security scope is valid, but it is not registered by default. For more information, see the documentationSimpleThreadScope
。 For more information on how to register and customize scopes, see custom scopes
1.5.1 singleton bean scope
Single casebean
Only one shared instance is managed by the container, and all pairs havebean
Define matchingID
Ofbean
Will cause the specificbean
Instance bySpring
Container returns. In another way, when you define abean
And its scope is a singleton,Spring IoC
Container creation viabean
An instance of a defined object definition. This singleton is stored in the cache and named forbean
All requests and references for are returned as cached objects. The following image shows a single examplebean
How scopes work:
Spring
Single example ofbean
Concept and inGoF
The singleton patterns in the design pattern book are different.GoF
The scope corresponding to the singleton hard coding, for example: only one object instance of a specific class is available for eachClassLoader
Create only one object instance. It is better toSpring
The scope of the singleton is described as each container and eachbean
(Note:GoF
Singleton in design patternbean
It’s about the differenceClassLoader
Yes, andSpring
The singleton of is for different container levels). This means that if theSpring
Container defines abean
,Spring
Container passing throughbean
Creates an instance of the defined class. staySpring
The singleton scope in is the default. To define abean
For example, you can define abean
This is similar to the following example:
<bean id="accountService" class=" com.something.DefaultAccountService / >
1.5.2 prototype scope
Non singleton prototypebean
The scope deployment result is specified in each requestbean
You will create abean
example. That is,bean
Injected into othersbean
Or through the containergetBean()
Method calls create a newbean
。 Typically, prototype scope is used for all stateless beans and statefulbean
Use singletonbean
Scope.
The following figure illustrates thisSpring
Singleton scope of:
Data access object(DAO
)It is not usually configured as a prototype because typicallyDAO
No session state is maintained. We can reuse the core of the singleton diagram more easily.
The following example is shown inXML
Define a prototype inbean
:
<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>
Compared with other scopes,Spring
There is no management prototypebean
The complete life cycle of. The container instantiates, configures, or otherwise assembles the prototype object and hands it over to the client without further recording the prototype instance. Therefore, although the initialization lifecycle callback function is called back on all objects regardless of scope,In the prototype case, the configuration destroy lifecycle callback is not called back。 The client code must clear the objects in the scope of the prototype and release the prototypeBean
Expensive resources occupied. In order to letSpring
Container release prototype scopebean
Please try to use custombean
The post processor contains thebean
The reference resource can be released through the post processor.
in some ways,Spring
The container is within the scope of the prototypebean
The role isJava new
Operator. All lifecycle management beyond this point must be handled by the client. (more aboutSpring
In containerbean
Lifecycles, viewing lifecycle callbacks)
1.5.3 dependency between singleton and prototype beans
When you use dependency prototypesbean
Singleton scope ofbean
The prototype is referenced by a single instancebean
)It should be noted that these dependencies are resolved at initialization time. So if you rely on injecting a prototypebean
To a singletonbean
A new prototypebean
Is initialized and dependency injected into a singletonbean
。 The prototype instance is the only one provided to the singleton scopebean
An example of. (Note: when a single instance references a prototype bean, there will be only one prototype bean)
However, suppose you want singleton scopebean
Get prototype scope repeatedly at run timebean
A new instance of. You can’t rely on injecting a prototypebean
To a singletonbean
Because the injection occurs only once, whenSpring
Container instantiation singletonbean
, parsing and injecting its dependencies. If you need a prototype more than once at run timebean
View method injection
1.5.4 Request, Session, Application, and WebSocket Scopes
request
、session
、application
, andwebsocket
Scope is only used by youSpring
OfApplicationContext
Implementation (for example:XmlWebApplicationContext
)Is valid. If you combine these scopes with the regularSpring IoC
Container (e.gClassPathXmlApplicationContext
)When used together, aIllegalStateException
The unknown exception is thrownbean
Scope.
-
Initialize web configuration
To support the scope of these beans in
request
、session
、application
, andwebsocket
Level (WEB scope bean). Some minor initialization configuration is required before you define your bean. (this initialization installation is not required for standard scopes:singleton
、prototype
)。This specific initialization depends on how you complete the installation
Servlet
Environmental Science.If
Spring Web MVC
Access scope inbean
In fact, theSpring
DispatcherServlet
No special settings are required in the request to be processed.DispatcherServlet
All relevant States have been exposed.If you use
Servlet 2.5
Web
Container, request processing inSpring
OfDispatcherServlet
External (e.g. when usingJSF
orStructs
)You need to registerorg.springframework.web.context.request.RequestContextListener
、ServletRequestListener
。 aboutServlet 3.0+
This can be done by using theWebApplicationInitializer
The interface is programmed. Or, for old containers, add the following statement to yourweb
application programweb.xml
Document:<web-app> ... <listener> <listener-class> org.springframework.web.context.request.RequestContextListener </listener-class> </listener> ... </web-app>
Or, if you have problems with your listener settings, consider using
Spring
OfRequestContextFilter
。 Filter mapping depends on the surroundingWeb
Application configuration. So you have to change it appropriately. The following list showsweb
application programfilter
Part of the configuration:<web-app> ... <filter> <filter-name>requestContextFilter</filter-name> <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class> </filter> <filter-mapping> <filter-name>requestContextFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ... </web-app>
DispatcherServlet
、RequestContextListener
andRequestContextFilter
It’s the same thing that’s going to happenHTTP
The request object is bound to the thread that serves the request. This makesrequest
andsession
The scope bean is available further down the call chain. -
Request
ScopeConsider the following XML about
bean
Definition of:<! -- request scope is request -- >
Spring
Container by usingLoginAction
Bean is defined as eachHTTP
Create aLoginAction
New instance bean. in other words,loginAction
The scope of the bean isHTTP
Request level. You can change the internal state of the created instance as needed. Because from the sameloginAction
Other instances created by the bean definition do not see these changes in state. When the request is processed, the scope of the bean changes fromrequest
discard. (Note:scope="request"
Each request is thread level isolated and does not interfere with each other)When using annotations to drive components or
Java Config
When,@RequestScope
Annotations can assign a component to arequest
Scope. The following example shows how to use:@Requestscope / / specify the scope access as request
-
Session scope
Consider the following
bean
DefinedXML
to configure:<bean id="userPreferences" class="com.something.UserPreferences" scope="session"/>
Spring
Container by usinguserPreferences
The bean of is defined as a singleHTTP
Session
Create aUserPreferences
A new instance of. let me put it another way,userPreferences
Beans work effectively at the HTTP session level. Like request scoped beans, you can change the internal state of the created instance as needed, knowing that others are also using the same`userPreferences
The HTTP session instance of the instance created by the bean definition also does not see these state changes because they are specific to a single HTTP session. WhenHTTP
When the session is eventually discarded, theHTTP
Conversationalbean
It will also be discarded.When using annotations to drive components or
Java Config
When,@SessionScope
Annotations can assign a component to asession
Scope. The following example shows how to use:@SessionScope @Component public class UserPreferences { // ... }
-
Application scope
Consider the following XML about
bean
Definition of:<bean id="appPreferences" class="com.something.AppPreferences" scope="application"/>
Spring
Container by usingappPreferences
Is defined as theWeb
Application creates aAppPreferences
A new instance of the bean. in other words,appPreferences
The scope ofServletContext
And as a regularServletContext
Property is stored. This andSpring
The singleton bean for is similar, but with two important differences: eachServletContext
It’s a singleton, not eachSpring
OfApplicationContext
(in the givenWeb
There may be more than one in the application), and it is actually exposed, so as aServletContext
Property is visible.When using annotations to drive components or
Java Config
When,@ApplicationScope
Annotations can assign a component to aapplication
Scope. The following example shows how to use:@ApplicationScope @Component public class AppPreferences { // ... }
-
Scope bean as dependency
The spring IOC container not only manages the instantiation of objects (beans), but also the connections of collaborators (or dependencies). For example, if you want to inject an HTTP request scoped bean into another bean with a longer scope, you can choose to inject an AOP proxy instead of a bean with a defined scope. That is, you need to inject a proxy object that exposes the same public interface as the scope object, but you can also retrieve the actual target object from the relevant scope (such as HTTP request) and delegate the method call to the actual object.
Here it is
bean
The scope is between singletons that you can use<aop:scoped-proxy/>
。 Then, through a serializable intermediate proxy reference, the target singleton can be retrieved during deserializationbean
。When stated
<aop:scoped-proxy/>
Prototype scopebean
Each method call to the shared proxy causes a new target instance to be created and the call is then forwarded to that target instance.Similarly, scope proxies are not accessed from shorter scopes in a lifecycle safe manner
bean
The only way. You can also declare your injection point (i.e., constructor orSetter
Parameter or auto injection field) for example:ObjectFactory<MyTargetBean>
, allowedgetObject()
Call to retrieve the current instance on demand every time it is needed – no instances are kept or stored separately.As an extension variant, you can declare
ObjectProvider<MyTargetBean>
Provides additional ways to obtain, includinggetIfAvailable
andgetIfUnique
。This variant of jsr-330 is called
Provider
And withProvider <MyTargetBean>
Statement and corresponding to each retrieval attemptget()
Call. For more details on the overall jsr-330, see here.In the following example, only one line of configuration is required, but it is important to understand the reasons behind it:
<?xml version="1.0" encoding="UTF-8"?>
- This line defines the agent.
Create a proxy by inserting a child<aop:scoped-proxy/>
Element to a scopebean
Definition (see select proxy type to create and schema based XML configuration). Why are thesebean
Is defined inrequest
、session
And custom scopes are required<aop:scoped-proxy/>
Elements? Consider the following singletonbean
Define and compare it to what needs to be defined for the above scope (note, belowuserPreferences
Incomplete bean definition)
<! -- No< aop:scoped-proxy/ >Elements -- >
In the previous example, the singleton bean(userManager
)Is injected with a reference toHTTP
Session
Scopedbean
(userPreferences
)。 The salient point is thatuserManager
Bean is a singleton bean: this instance is initialized once per container value, and its dependencies (in this case, there is only one,userPreferences
Bean) is injected only once. This means thatuserManager
Beans run only in the sameuserPreferences
That’s the initial injection.
When injecting a short life cycle scopebean
To a long lifecycle scopebean
This is not the way we expect (e.g. injecting an HTTPSession
Scope collaboratorsbean
As a dependency injection into the singletonbean
)。 Instead, you only need oneuserManager
Object, and in theHTTP
You need an HTTP session specificuserPreferences
Object. Therefore, the container creates an object that exposes theUserPreferences
Classes are identical public interfaces (ideally, objects areUserPreferences
Instance) from the scope mechanism (HTTP request,Session
And so on) to get the realUserPreferences
Object. The container injects the proxy object into theuserManager
Bean, which doesn’t know thisUserPreferences
The reference is a proxy. In this case, whenUserManager
Instance call in dependency injectionUserPreferences
Object, it actually calls the method on the proxy. Then the proxy from (in this case)HTTP
Get the actualUserPreferences
Object and delegate the method call to the retrieved actualUserPreferences
Object.
Therefore, in therequest-scoped
andsession-scoped
You need the following (correct and complete) configuration to inject the bean into the collaboration object, as shown in the following example:
<bean id="userPreferences" class="com.something.UserPreferences" scope="session">
<aop:scoped-proxy/>
</bean>
<bean id="userManager" class="com.something.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
-
Agent type selection
By default, when
Spring
The container isbean
Create a proxy, thisbean
adopt<aop:scoped-proxy/>
Element is marked based onCGLIB
The class proxy for is created.CGLIB
Proxy interceptor only public methods are called! Do not call non-public methods on the proxy.Or, you can create a scope for
bean
to configureSpring
Container creation standardJDK
Interface based proxy by specifying<aop:scoped-proxy/>
Elementalproxy-target-class
Property value isfalse
。 Using JDK based proxies means that you don’t need other libraries in the application classpath to affect such proxies. But it also means scopeBean
Must implement at least one interface and be scopedBean
All collaborators injected into it must reference this through one of their interfacesBean
。 The following example shows an interface based proxy:<!-- DefaultUserPreferences implements the UserPreferences interface -->
More details about choosing based on
class
Or based on the interface proxy, refer to the proxy mechanismReference code:
com.liyong.ioccontainer.starter.XmlBeanScopeIocContainer
1.5.5 custom scope
bean
The scope mechanism is extensible. You can define your own scopes or even redefine existing scopes, although the latter is considered bad practice, you cannot override built-in singletons and prototype scopes.
-
Create a custom scope
To integrate your custom scopes into
Spring
Container, you need to implementorg.springframework.beans.factory.config.Scope
Interface, described in this chapter. For ideas on how to implement your own scope, seeScope
Implementation provides information aboutSpring
Framework itself andScope
Which details the method you need to implement.Scope
Interface has four methods to get objects from the scope, remove them from the scope, and have them destroyed.For example:
Sesson
Ofscope
Implement returnSeason
Scopebean
(if it doesn’t exist, this method returns a new onebean
Instance, which is bound to the session for future reference). The following method returns the object from the underlying scope:Object get(String name, ObjectFactory<?> objectFactory)
For example:
Session
Ofscope
Remove the season scopebean
From the bottomSession
。 Object should be returned, but if the name specified by the object does not exist, you can return itnull
。 The following method removes the object from the underlying scope:Object remove(String name)
The following methods register the callbacks that should be executed when destroying the scope or the specified object in the scope:
void registerDestructionCallback(String name, Runnable destructionCallback)
Check Javadoc or
Spring
Scope implements information about more destruction callbacks.The following method gets the session identifier of the underlying scope:
String getConversationId()
This means that each scope is different. about
Session
Implementation of the scope, which can beSession
Identifier. -
Using custom scopes
Before you write and test one or more customizations
Scope
You need to make it happenSpring
The container knows your new scope. The following methods areSpring
Main methods to register new scopes in containers:void registerScope(String scopeName, Scope scope);
This method is used in
ConfigurableBeanFactory
Is defined on the interface, which can be accessed through theSpring
Most of the specificApplicationContext
ImplementationBeanFactory
Property.registerScope(..)
The first parameter of the method is the unique name about the scope.Spring
Examples of such names in the container itself include singletons and prototypes.registerScope(..)
The second parameter of the method is customScope
realizationSuppose you write your custom
Scope
Implement and register it as in the example below.The following example uses
SimpleThreadScope
It includesSpring
But it is not registered by default. It’s the same for your own custom scope implementation.Scope threadScope = new SimpleThreadScope();
You can then create bean definitions according to the scope rules of your custom scope, as follows:
<bean id="..." class="..." scope="thread">
By customizing
Scope
Implementation, you are not limited to registering scopes programmatically. You can register scope declaratively by using theCustomScopeConfigurer
, similar to the following example:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <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> <bean id="thing2" class="x.y.Thing2" scope="thread"> <property name="name" value="Rick"/> <aop:scoped-proxy/> </bean> <bean id="thing1" class="x.y.Thing1"> <property name="thing2" ref="thing2"/> </bean> </beans>
When in
FactoryBean
Configuration in implementation<aop:scoped-proxy/>
The factory is scopedbean
Itself, not fromgetObject()
Returns the object.Reference code:
com.liyong.ioccontainer.starter.XmlCustomScopeIocContainer
author
Personally engaged in the financial industry, I have worked in Chongqing’s first-class technical team, such as yijifu, Sijian technology, a car Hailing platform, etc. at present, I am in charge of the construction of unified payment system in a bank. I have a strong interest in the financial industry. At the same time, it also practices big data, data storage, automatic integration and deployment, distributed microservices, responsive programming, artificial intelligence and other fields. At the same time, it is also keen to share technology and create official account and blog site.
Blog address: http://youngitman.tech
CSDN: https://blog.csdn.net/liyong1…
The official account of WeChat:
Technical exchange group: