Automatic assembly of Bean
- Automatic assembly is a way to use spring to meet bean dependencies
- spring will find the bean that a bean depends on in the application context.
There are three assembly mechanisms for bean s in Spring:
- Explicit configuration in xml (this is the way we have done before);
- Explicit configuration in java;
- Implicit bean discovery mechanism and automatic assembly.
Here we mainly talk about the third kind: automatic assembly bean.
Spring's automatic assembly needs to be implemented from two perspectives, or two operations:
- Component scanning: spring will automatically discover the bean s created in the application context;
- Autowiring: spring automatically satisfies the dependencies between bean s, which is what we call IoC/DI;
1. Construction of test environment
- Create a new project
- Create two new entity classes. Cat Dog has a method called
public class Cat { public void shout(){ System.out.println("miao~"); } }
public class Dog { public void shout(){ System.out.println("wang~"); } }
- Create a new User class User
public class People { private Dog dog; private Cat cat; private String name; // get set toString constructor }
- Write the Spring configuration file. applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="cat" class="com.xxc.pojo.Cat"/> <bean id="dog" class="com.xxc.pojo.Dog"/> <bean id="people" class="com.xxc.pojo.People"> <property name="name" value="Jiangnan"/> <property name="cat" ref="cat"/> <property name="dog" ref="dog"/> </bean> </beans>
- test
public class MyTest { @Test public void test(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); People people = context.getBean("people", People.class); people.getCat().shout(); people.getDog().shout(); } }
Normal output indicates that there is no problem with the environment.
2. byName
autowire byName
In the process of manually configuring xml, errors such as missing letters and case often occur, so it is impossible to check them, which reduces the development efficiency.
Using automatic assembly will avoid these errors and simplify the configuration.
Modify the bean configuration and add an attribute autowire = "byName"
<bean id="people" class="com.xxc.pojo.People" autowire="byName"> <property name="name" value="Jiangnan"/> </bean>
test
public class MyTest { @Test public void test(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); People people = context.getBean("people", People.class); people.getCat().shout(); people.getDog().shout(); } }
Test again, and the result is still output successfully!
Note: when ByName is used for automatic assembly, ensure that the value of id is consistent with the value after set in the entity class, otherwise the real setXXX will not be executed and the object will not be initialized, so a null pointer error will be reported when calling.
Summary:
When a bean node has the attribute autowire byName.
- All set method names in its class, such as setCat, will be searched to obtain the string with set removed and lowercase, that is, cat.
- Go to the spring container to find whether there is an object with this string name id.
- If yes, take out the injection; If not, a null pointer exception is reported.
3. byType
autowire byType
Using autowire byType first needs to ensure that objects of the same type are unique in the spring container. If it is not unique, it will report an exception that is not unique.
NoUniqueBeanDefinitionException
Modify bean configuration, autowire = "byType"
<bean id="people" class="com.xxc.pojo.People" autowire="byType"> <property name="name" value="Jiangnan"/> </bean>
Test, normal output.
If we register a cat bean object.
<bean id="cat" class="com.xxc.pojo.Cat"/> <bean id="dog" class="com.xxc.pojo.Dog"/> <bean id="dog1" class="com.xxc.pojo.Dog"/> <bean id="people" class="com.xxc.pojo.People" autowire="byType"> <property name="name" value="Jiangnan"/> </bean>
The test will report an error: NoUniqueBeanDefinitionException
Delete cat2 and change the bean name of cat! Test! Because it is assembled by type, no exception will be reported and the final result will not be affected. Even removing the id attribute does not affect the result. In fact, it is to ensure that only one entity class is injected.
This is automatic assembly according to type!
4. Use notes
jdk1.5 start supporting annotations, spring 2 5. Begin to fully support annotation
Preparation: inject attributes by annotation.
- Introduce the context file header into the spring configuration file
xmlns:context="http://www.springframework.org/schema/context" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
- Enable attribute annotation support!
<context:annotation-config/>
4.1 @Autowired
- @Autowired is automatically transferred by type and does not support id matching.
- You need to import the package of spring AOP!
xmlns:aop="http://www.springframework.org/schema/aop" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
test
Remove the set method from the People class and use @ Autowired annotation (set method is optional)
public class People { @Autowired private Dog dog; @Autowired private Cat cat; private String name; }
Test and output the results successfully.
The content of the configuration file at this time
applicationContext.xml
<?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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <context:annotation-config/> <bean id="cat" class="com.xxc.pojo.Cat"/> <bean id="dog" class="com.xxc.pojo.Dog"/> <bean id="people" class="com.xxc.pojo.People"/> </beans>
Knowledge points:
@Autowired(required=false) Description: false, the object can be null; true, the object must be saved and cannot be null.
//If the allowed object is null, set required = false, and the default is true @Autowired(required = false) private Cat cat;
4.2 @Qualifier
- @Autowired is automatically assembled according to the type. With @ Qualifier, it can be automatically assembled according to byName
- @Qualifier cannot be used alone.
test
- Modify the content of the configuration file to ensure that there are objects of type. And the name is not the default name of the class.
<bean id="cat1" class="com.xxc.pojo.Cat"/> <bean id="cat2" class="com.xxc.pojo.Cat"/> <bean id="dog1" class="com.xxc.pojo.Dog"/> <bean id="dog2" class="com.xxc.pojo.Dog"/>
-
No Qualifier test is added, and an error is reported directly
-
Add a Qualifier annotation to the attribute
@Autowired @Qualifier(value = "dog1") private Dog dog; @Autowired @Qualifier(value = "cat2") private Cat cat;
- test
4.3 @Resource
- @If the Resource has a specified name attribute, first search the assembly by name according to the attribute;
- Secondly, assemble in the default byName mode;
- If none of the above is successful, it will be assembled automatically by byType.
- If they are not successful, an exception is reported.
Entity class:
@Resource private Dog dog; @Resource(name = "cat2") private Cat cat; private String name;
applicationContext.xml
<bean id="cat1" class="com.xxc.pojo.Cat"/> <bean id="cat2" class="com.xxc.pojo.Cat"/> <bean id="dog" class="com.xxc.pojo.Dog"/> <bean id="people" class="com.xxc.pojo.People"/>
test
Test successful!
If we modify ApplicationContext xml
<bean id="cat1" class="com.xxc.pojo.Cat"/> <bean id="dog" class="com.xxc.pojo.Dog"/>
Only annotations are retained on entity classes
@Resource private Dog dog; @Resource private Cat cat;
test
Conclusion: @ Resource searches byName first. If it fails; The byType search is successful.
5. Summary
@Similarities and differences between Autowired and @ Resource:
- @Both Autowired and @ Resource can be used to assemble bean s. Can be written on fields or setter methods.
- @Autowired is assembled by type by default (belonging to the spring specification). By default, dependent objects must exist. If null value is allowed, its required attribute can be set to false, such as @ Autowired(required=false). If we want to use name assembly, it can be used in combination with @ Qualifier annotation.
- @Resource (belonging to J2EE specification) is assembled by name by default, and the name can be specified through the name attribute. If the name attribute is not specified, when the annotation is written on the field, the default is to take the field name to search by name. If the annotation is written on the setter method, the default is to take the attribute name for assembly. Assemble by type when no bean matching the name is found. However, it should be noted that once the name attribute is specified, it will only be assembled according to the name.
Their functions are the same. They all inject objects by annotation, but the execution order is different@ Autowired byType first, @ Resource byName first.