Automatic assembly instructions
- 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;
- Explicit configuration in java;
- Implicit bean discovery mechanism and automatic assembly.
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;
The combination of component scanning and automatic assembly exerts great power to minimize the configuration of display.
First, build the test environment
1. Create two 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~"); } }
2. Create a new User class User
public class User { private Cat cat; private Dog dog; private String str; }
3. Write Spring configuration file
<?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="dog" class="com.kuang.pojo.Dog"/> <bean id="cat" class="com.kuang.pojo.Cat"/> <bean id="user" class="com.kuang.pojo.User"> <property name="cat" ref="cat"/> <property name="dog" ref="dog"/> <property name="str" value="qinjiang"/> </bean> </beans>
4. Test
public class MyTest { @Test public void testMethodAutowire() { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); User user = (User) context.getBean("user"); user.getCat().shout(); user.getDog().shout(); } }
The first type: autowire byName (automatic assembly by name)
Modify the bean configuration and add an attribute autowire="byName"
<bean id="user" class="com.kuang.pojo.User" autowire="byName"> <property name="str" value="qinjiang"/> </bean>
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 any, take out the injection; If not, a null pointer exception is reported.
Second: 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 the bean configuration of user: autowire="byType"
<bean id="dog" class="com.kuang.pojo.Dog"/> <bean id="cat" class="com.kuang.pojo.Cat"/> <bean id="cat2" class="com.kuang.pojo.Cat"/> <bean id="user" class="com.kuang.pojo.User" autowire="byType"> <property name="str" value="qinjiang"/> </bean>
Test, 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.
This is automatic assembly according to type!
Third: use annotations
Preparation: inject attributes by annotation.
1. 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
2. Enable attribute annotation support!
<context:annotation-config/>
@Autowired
- @Autowired is automatically transferred by type and does not support id matching.
- You need to import the package of spring AOP!
@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;
Test:
1. Remove the set method in the User class and use the @ Autowired annotation
public class User { @Autowired private Cat cat; @Autowired private Dog dog; private String str; public Cat getCat() { return cat; } public Dog getDog() { return dog; } public String getStr() { return str; } }
2. The contents of the configuration file are displayed
<context:annotation-config/> <bean id="dog" class="com.kuang.pojo.Dog"/> <bean id="cat" class="com.kuang.pojo.Cat"/> <bean id="user" class="com.kuang.pojo.User"/>
3. Test, output results successfully!
@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:
1. 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="dog1" class="com.kuang.pojo.Dog"/> <bean id="dog2" class="com.kuang.pojo.Dog"/> <bean id="cat1" class="com.kuang.pojo.Cat"/> <bean id="cat2" class="com.kuang.pojo.Cat"/>
2. No Qualifier test is added, and an error is reported directly
3. Add a Qualifier annotation to the attribute
@Autowired @Qualifier(value = "cat2") private Cat cat; @Autowired @Qualifier(value = "dog2") private Dog dog;
4. Test, successful output!
@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 there is no exception, it will not succeed.
Test 1:
Entity class:
public class User { //If the allowed object is null, set required = false, and the default is true @Resource(name = "cat2") private Cat cat; @Resource private Dog dog; private String str; }
beans.xml
<bean id="dog" class="com.kuang.pojo.Dog"/> <bean id="cat1" class="com.kuang.pojo.Cat"/> <bean id="cat2" class="com.kuang.pojo.Cat"/> <bean id="user" class="com.kuang.pojo.User"/>
Test result: OK
Test 2:
Configuration file 2: beans XML, delete cat2
<bean id="dog" class="com.kuang.pojo.Dog"/> <bean id="cat1" class="com.kuang.pojo.Cat"/>
Only annotations are retained on entity classes
@Resource private Cat cat; @Resource private Dog dog;
Result: OK
Conclusion: byName search first failed; The byType search is successful.
Summary:
@Similarities and differences between Autowired and @ Resource:
1. Both @ Autowired and @ Resource can be used to assemble bean s. Can be written on fields or setter methods.
2. @ 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
3. @ Resource (belonging to J2EE complex return), 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 first byType then byName, @ Resource first byName then byType.