In the previous sections, through the xml configuration file, can be implemented to control inversion Spring dependency injection. However, if a class, there are many attributes, rely more than one goal, this time based on the way this xml configuration is very cumbersome. Fortunately, Spirng offers several tips that can help us reduce the number of configuration xml
- Automatic assembly (autowiring) can help reduce or even eliminate configuration <property> element and <constructor-arg> elements, so spring assembly dependencies automatically recognize how the Bean
- Automatic detection (AutoDiscovery) goes a step further than the automatic assembly, which can automatically identify let Spring class needs to be configured Spring Bean, thereby reducing the use of <bean> element
An automatic assembly Bean Property
In type 1, four automatic assembly
- Bean to Bean byName-- and other attributes with the same name (or ID) to the corresponding properties of the automatic assembly of Bean. If there is no property with the name that matches the Bean, the property is not assembled.
- Other Bean byType-- having the same type of Bean to Bean automatic assembly properties to the corresponding properties of automatic assembly of Bean. If there is no match with the type of the attribute of the Bean, the property is not fitted.
- constructor-- the Bean and the constructor parameter having the same type of other automatic assembly Bean to Bean constructor corresponding to the ginseng.
- autodetect-- first try constructor for automatic assembly. If that fails, try using byType for automatic assembly.
Here, we demonstrate only the first byName:
Step 1: Create persistence layer UserDao
1 package com.justnow.dao; 2 3 import com.justnow.domain.User; 4 5 public class UserDao { 6 public void findAll(User user){ 7 System.out.println(user); 8 } 9 }
Step 2: Create implementation class UserServiceImpl business layer by set methods dependency injection implemented.
. 1 Package com.justnow.service.impl; 2 . 3 Import com.justnow.dao.UserDao; . 4 Import com.justnow.domain.User; . 5 Import com.justnow.service.IUserService; . 6 . 7 public class UserServiceImpl the implements IUserService { . 8 Private UserDao userDao; . 9 Private String otherProperty; 10 . 11 // must have property set methods, or can not dependency injection 12 is public void setUserDAO (UserDao userDao) { 13 is the this .userDao = userDao; 14 } 15 16 public void setOtherProperty(String otherProperty) { 17 this.otherProperty = otherProperty; 18 } 19 20 public void findAll(User user) { 21 userDao.findAll(user); 22 System.out.println(otherProperty); 23 } 24 }
The third step: write the configuration file of the Spring Framework
Set autowire properties in the bean tag for byName: If a Bean id appears in the configuration file is (as userServiceImpl the attribute name userDao) userDao, you can achieve automatic assembly
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans.xsd"> 6 <bean id="userService" class="com.justnow.service.impl.UserServiceImpl" autowire="byName"> 7 <property name="otherProperty" value="利用property标签注入的值"/> 8 </bean> 9 10 <bean id="userDao" class="com.justnow.dao.UserDao"/> 11 </beans>
Step Four: Test
1 @Test 2 public void test(){ 3 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); 4 IUserService userService = (IUserService) context.getBean("userService"); 5 User user = new User(); 6 user.setId(1); 7 user.setName("justnow"); 8 user.setMoney(1.0f); 9 userService.findAll(user); 10 }
result:
UserDao modify the bean id value userDao2, as follows:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans.xsd"> 6 <bean id="userService" class="com.justnow.service.impl.UserServiceImpl" autowire="byName"> 7 <property name="otherProperty" value="利用property标签注入的值"/> 8 </bean> 9 10 <!-- 11 <bean id="userDao" class="com.justnow.dao.UserDao"/> 12 --> 13 <bean id="userDao2" class="com.justnow.dao.UserDao"/> 14 </beans>
Look at the test results:
After development, the assembly is substantially less automatic manner by four, using the assembly annotation! So, the next three are no longer demonstrated.
https://github.com/justn0w/javawebdemo/tree/master/spring/Spring_Demo3
c6e5dccfcacb13c42db41a2ed7b1145ddef700b7
2, automatic assembly using annotations
Use annotations automated assembly attribute Bean, you can no longer write tedious xml file, thus turning their attention to the business logic of the project. In future development, play a mainstay of notes!
Spring container assembly annotation is disabled by default. Therefore, before using automated assembly annotation-based, we need to enable it in the Spring configuration file. The easiest way is to enable the use Spring context namespace configuration <context: annotation-config> element, as follows:
<?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"
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">
<context:annotation-config />
White on red are a new naming convention.
(1) @Autowired
A scenario: the method used in the set
The first step: Modify UserServiceImpl implementation class, add annotations on setUserDao this method
. 1 public class UserServiceImpl the implements IUserService { 2 Private UserDao userDao; . 3 Private String otherProperty; . 4 // must have property set methods, or can not dependency injection . 5 @Autowired . 6 public void setUserDAO (UserDao userDao) { . 7 the this .userDao = userDao ; . 8 } . 9 public void setOtherProperty (String otherProperty) { 10 the this .otherProperty = otherProperty; . 11 } 12 is 13 is public void findAll(User user) { 14 userDao.findAll(user); 15 System.out.println(otherProperty); 16 } 17 }
Step two: modify the configuration file, as follows:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context.xsd"> 9 <context:annotation-config /> 10 <bean id="userService" class="com.justnow.service.impl.UserServiceImpl"> 11 <property name="otherProperty" value="利用property标签注入的值"/> 12 </bean> 13 14 <bean id="userDao10" class="com.justnow.dao.UserDao" /> 15 </beans>
The third step: test
1 @Test 2 public void test(){ 3 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); 4 IUserService userService = (IUserService) context.getBean("userService"); 5 User user = new User(); 6 user.setId(1); 7 user.setName("justnow"); 8 user.setMoney(1.0f); 9 userService.findAll(user); 10 }
result:
This result is consistent with the results of automatic assembly by name!
Scene 2: labeling any of the methods referenced in need automatic assembling Bean
For example, the following method:
@Autowired pubilc void differentWay(UserDao userdao){ this.userdao=userdao; }
This method is not set method, but this userDao Bean annotated by automatic assembly
Scene Three: mark in the constructor
as follows:
1 @Autowired 2 public UserServiceImpl(UserDao userDao){ 3 this.userDao = userDao; 4 }
Scene Four: direct labeling Properties, and remove the setter method
In our development process, using this method to achieve automatic assembly, use very frequently.
The first step: Modify UserServiceImpl implementation class, add annotations on private property, and remove the setter method
1 public class UserServiceImpl implements IUserService { 2 @Autowired 3 private UserDao userDao; 4 5 private String otherProperty; 6 7 public void setOtherProperty(String otherProperty) { 8 this.otherProperty = otherProperty; 9 } 10 11 public void findAll(User user) { 12 userDao.findAll(user); 13 System.out.println(otherProperty); 14 } 15 }
Test case:
@Autowired not limited to the private key. Even if the property is private instance variable, it can still be assembled automatically!
Automated assembly, not just to help us write <property> and <constructor-arg> element, we still need to use <bean> element to display the definition of Bean.
Second, the automatic detection Bean
This is another technique of Spring, <context: component-scan> element other complete <context: annotation-config> as an outer work and also allows automatic detection Spring Bean definitions and Bean. It is to say, no longer in use <bean> element, Spring applications are able to achieve most of Bean defined and assembly.
Use as follows:
<context:component-scan
base-package="com.justnow">
</context:component-scan>
<Context: component-scan> element will scan the specified package and all admit, and find out automatically registered as a Spring Bean class. base-package attribute identifies the <context: component-scan> element of the scanned package.
So, <context: component-scan> How do they know which classes need to register it as a Spring Bean?
2.1 annotation, tagging Bean to automatically detect
(1) @Component
Role: to let spring resources management. Bean corresponds to a configuration in xml
Property: value: specifies the bean id. If you do not specify a value attribute, the default bean id of the current class is the class name (first letter lowercase).
(2) @Controller @Service @Repository
The three notes are derived for the first notes of their role level attributes are exactly the same. But it provides a more explicit semantic.
@Controller: General notes for the presentation layer. That in SpringMVC
@Service: general business for the annotation layer.
@Repository: generally used for annotation persistence layer.
(3) @Autowired
This annotation is equivalent to using the autodetect first type of automatic assembly. First, try to use the constructor for automatic assembly. If that fails, try using byType for automatic assembly.
When using this property annotation injection, setter method may be omitted!
2.2 Scanning filter assembly
If the need arises next, we use <context: component-scan> scan the com.justnow, but for com.justnow.controller package, we do not want to be scanned, this time, you need to use <context: include -filter> and <context: exclude-filter> subelement adjust the scanning behavior.
(1) <context:include-filter>
The element further comprises the following Attributes: type and expression, the following use
type and expression of
The first match: Scanning filter using the classes specified annotation marked. Specifies the attributes to be scanned by the expression comment
The second match: scanning and derived (make or inherited) expression The attribute classes that specify the type of filter.
Third with: class filters that scan expression attribute specified AspectJ expression matched.
With fourth: scanning the filter expression attribute category name specified by the regular expression matching that class.
The fifth match: using a custom org.springframework.core.type.TypeFilter achieve class that is specified by the expression attribute.
for example:
1 <context:component-scan base-package="com.justnow"> 2 <context:include-filter type="assignable" expression="com.justnow.service.IUserService"/> 3 </context:component-scan>
Scan only achieved at the interface class com.justnow.service.IUSerService com.justnow package.
(2) <context: exclude-filter>, which is registered as a Spring Bean class does not.
Such as:
<! - 1, when configuring the spring to create a container to be scanned package -> < context: the Component-Scan Base-Package Penalty for = "com.justnow" > ! <- formulate sweeping package rules, does not scan @Controller annotated JAVA class, or to the other scan -> < context: the exclude filter- type = "Annotation" expression the = "org.springframework.stereotype.Controller" /> </ context: Component-scan >
That does not scan @Controller annotated java classes, but also other scans.
reference:
https://docs.spring.io/spring/docs/4.3.25.RELEASE/spring-framework-reference/htmlsingle/
Third, the summary
1, minimizing the Spring XML configuration is achieved by automatic detection and automatic assembly. Let us no longer dependent on the former <property> and <constructor-org> element, which can liberate Bean create this cumbersome process for each class.
2, there is a Java-based Spring configuration does not sum up, of course, this method is also very practical.