Assembly by Condition
Bean
is when a particular condition is met the spring container is created in the bean,spring by @conditional annotations to implement the conditional configuration bean
PackageCom.sl.ioc;ImportOrg.springframework.context.annotation.Bean;Importorg.springframework.context.annotation.Conditional;Importorg.springframework.context.annotation.Configuration; @Configuration Public classanimalconfig {@Bean ("Dog") @Conditional (dogcondition.class) PublicDog doginstance () {return NewDog (); } @Bean ("Cat") @Conditional (catcondition.class) PublicCat catinstance () {return NewCat (); } }
@Conditional and: Implementation of the Condition interface
Public@InterfaceConditional {/*** All {@linkCondition}s that must {@linkplaincondition#matches Match} * In order for the component to is registered. */Class<?extendsCondition>[] Value ();} Public InterfaceCondition {/*** Determine if the condition matches. * @paramContext The condition context *@parammetadata Metadata of the {@linkOrg.springframework.core.type.AnnotationMetadata Class} * or {@linkOrg.springframework.core.type.MethodMetadata Method} being checked *@return {@codetrue} if the condition matches and the component can be registered, * or {@codefalse} to veto the annotated component ' s registration*/ Booleanmatches (conditioncontext context, annotatedtypemetadata metadata);}
Conditional annotations Pass in a class through value, implementing the Condition interface, by implementing the matches method in the condition interface to determine if the bean needs to be assembled, or return true if the bean is required to satisfy the condition, or false
You define two classes that inherit the condition interface: Conditioncontext to find out if a dog or cat attribute exists in the current environment, and if so, create the corresponding Bean object, implemented as follows:
PackageCom.sl.ioc;Importorg.springframework.context.annotation.Condition;ImportOrg.springframework.context.annotation.ConditionContext;Importorg.springframework.core.env.Environment;ImportOrg.springframework.core.type.AnnotatedTypeMetadata; Public classDogconditionImplementsCondition {@Override Public Booleanmatches (conditioncontext context, annotatedtypemetadata Metadata) {Environment Environment=context.getenvironment (); Booleanflag= environment.containsproperty ("Dog"); returnFlag; }}
PackageCom.sl.ioc;Importorg.springframework.context.annotation.Condition;ImportOrg.springframework.context.annotation.ConditionContext;Importorg.springframework.core.env.Environment;ImportOrg.springframework.core.type.AnnotatedTypeMetadata; Public classCatconditionImplementsCondition {@Override Public Booleanmatches (conditioncontext context, annotatedtypemetadata Metadata) {Environment Environment=context.getenvironment (); Booleanflag= Environment.containsproperty ("Cat"); returnFlag; }}
PackageCom.sl.ioc;Importorg.springframework.stereotype.Component; @Component Public InterfaceAnimal {voidSay (); } PackageCOM.SL.IOC;Importorg.springframework.stereotype.Component; @Component Public classCatImplementsAnimal {@Override Public voidSay () {System.out.println ("I am a Cat"); }} PackageCom.sl.ioc;Importorg.springframework.stereotype.Component; @Component Public classDatImplementsAnimal {@Override Public voidSay () {System.out.println ("I am A Dog"); }}
Test code:
Public class TestClass { @Test publicvoid testgetdoinstance () { System.setproperty ( "Dog", "" ") ; New Annotationconfigapplicationcontext (animalconfig. Class); = context.getbeandefinitionnames (); for (String bean:beannames) { System.out.println (bean); }}}
Run the test to see that the beanname in the output will contain the bean of dog:
ambiguity processing of automatic assembly
Spring automatically assembles if there are multiple beans that match, then this prevents spring from being assembled by properties, constructors, or methods. In this case, spring provides a variety of options to solve this problem, you can choose a bean as the preferred bean, or use qualifiers to determine the unique bean
1: Use preferred bean
Spring provides @primary annotations to set the preferred bean, choosing to assemble the bean with @primary when the automatic assembly ambiguity is selected
Following the example code above, try loading the animal
@Component Public class animalinstance { @Autowired public Animal Animal; }
When spring attempts to inject an animal instance, because both dog and cat inherit from animal, there is ambiguity here, as the following specifies the preferred bean by using @primary
@Component @primary // Specify preferred Bean Public class Implements Animal { @Override publicvoid Say () { System.out.println (" I am a cat ");} }
You can also use the XML configuration to implement the:<bean> element to provide the primary property to set the preferred bean
<id= "Cat" class= "Com.sl.ioc.Cat"= "true" >
Test code:
Public class TestClass { @Test publicvoid testgetdoinstance () { // Application Context New Annotationconfigapplicationcontext (animalconfig. Class); = Context.getbean (animalinstance. Class); AnimalInstance.animal.Say (); }}
Operation Result:
The preference is simply to identify a preferred loaded bean, and if multiple @primary are configured, there will be a new ambiguity, and spring is still unable to complete the automatic assembly, which can be solved by the following qualifiers
2: Using qualifiers
Spring provides @qualifier annotations to specify the specific beans that you want to inject. For example, the above example, if you specify an injected dog:
Package Com.sl.ioc; Import org.springframework.beans.factory.annotation.Autowired; Import Org.springframework.beans.factory.annotation.Qualifier; Import org.springframework.stereotype.Component; @Component Public class animalinstance { @Autowired @Qualifier ("Dog") public Animal Animal; }
To explain: the @Qualifier ("dog") indicates that the specified bean has a "dog" qualifier, and if the bean does not specify a qualifier in spring, the default qualifier is used, that is, using Beanid as the qualifier. So the above is exactly using the ID of the dog bean as the qualifier. Can also be written as follows:
@Component @qualifier ( "Specialdog") // public class Dog implements animal{@Override public void Say () {System.out.println ( "I am a Dog"
@Component Public class animalinstance { @Autowired @Qualifier ("Specialdog") // Use the qualifiers defined above Public Animal Animal;}
Bean
the scope
The spring container, while creating a bean instance, also allows you to specify the scope of the bean instance, with a few common scopes:
1: Single-case scope (Singleton)
2: Prototype scope (PROTOTYPE)
3: Session scope (Sessions)
4: Requesting scope (Request)
5: Global Session scope (Globalsession)
Singleton scope
Throughout the application, the spring IOC container creates only one instance of the bean using the singleton pattern, and spring caches the bean instance, and any requests for that type of Beand will return the instance. Singleton is also the default scope for spring. This is done using XML configuration
<id= "Beanid" class= "com.sl.ioc.xxx" scope = "Singleton"></bean>
The <bean> element provides the scope property to set the singleton scope
The corresponding annotations:
@Scope (Configurablebeanfactory.scope_singleton)
Prototype prototype scope
Create a new instance of the bean each time it is injected or fetched from the spring container:
<id= "Beanid" class= "com.sl.ioc.xxx" scope = "Prototype"></bean>
The <bean> element provides the scope property to set the singleton scope
The corresponding annotations:
@Scope (Configurablebeanfactory.scope_prototype)
Session Sessions Scope
In a Web application, for each session, the spring container creates a bean instance based on the bean definition and is only valid in the current session sessions, and the XML is configured as follows:
<id= "Beanid" class= "com.sl.ioc.xxx" scope = "Session"></bean>
For an HTTP session,spring container, a new bean instance is created based on the bean definition, which is valid only within the current HTTP Session. You can change the internal state of the bean instance as needed without affecting the bean instances in the other HTTP session. When the HTTP session is eventually discarded, the beans inside the HTTP session scope will be destroyed.
Request Scope
<id= "Beanid" class= "com.sl.ioc.xxx" scope = "Globalsession"></bean>
In a Web application, for each request, the spring container creates a new bean instance based on the bean definition, valid only within the current request
<id= "Beanid" class= "com.sl.ioc.xxx" scope = "Request"></bean>
The bean instance is valid only within the current request and the bean is destroyed after the request processing is complete
Globalsession
Global Session Scope
Similar to the session scope, just the Web app that it uses for the portlet environment. If the non-portlet environment is treated as a session scope.
Spring temperature knows new-bean assembly (cont.)