Acacia meet know when? This night is a shame.

An overview of the

In the Spring framework, it is good practice to declare bean dependencies in configuration files because the Spring container can automatically assemble relationships between cooperating beans. This is called Spring autowiring.

The autowiring feature has four modes. These are no, byName, byType, and constructor.

Another automatic connection mode automatic detection has been deprecated. Docs says the AutoDetect option offers too much magic, and it’s better to use a more explicit declaration.

  • XMLThe default autowiring mode isno.
  • JavaThe default autowiring mode in the configuration isbyType.

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2019/10/23/16df66e3a65bb570~tplv-t2oaga2asx-image.image

Automatic assembly mode

  1. noThis option isspringThe default option for the framework, indicating that autowiring is turned offOFF. We have to startbeanUse in definition<property>The tag explicitly sets the dependency.
  2. byNameThis option is enabled based onbeanDependency injection of the name. inBeanThe attribute name is used to search for a match in the configuration file when the attribute is auto-assembled inBeanDefinition. If you find something like thisbean, it is injected into the property. If you can’t find onebean, an error is raised.
  3. byTypeThis option supports based onbeanType of dependency injection. inbeanThe class type of the attribute is used to search for a match in the configuration file when the attribute is auto-assembled inbeanDefinition. If you find something like thisbean, just inject it into the property. If you don’t find one like thisbean, an error is raised.
  4. constructorAutomatically assembles and via constructorsbyTypeSimilar, applies only to constructor parameters. In the auto assembly enabledbeanIn, it looks for the class type of the constructor parameters, and then performs an autotype assembly on all the constructor parameters. Note that if there is not a full constructor parameter type in the containerbean, will cause a fatal error.

@Autowiredannotations

In addition to the autowiring mode provided in the bean configuration file, you can specify autowiring in the bean class using the @AutoWired annotation. To use @AutoWired automatic injection in a bean class, you must first enable automatic injection in your Spring application using the following configuration.

Enable annotation configuration
<context:annotation-config />
Copy the code

In the configuration file is used AutowiredAnnotationBeanPostProcessor bean definition can achieve the same purpose.

<bean class ="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
Copy the code
use@Autowiredannotations

Now, with annotation configuration enabled, you feel free to use @AutoWired to automatically wire bean dependencies. This can be done in three ways:

@Autowiredattribute

Using @Autowired on attributes is equivalent to automatic injection via byType in configuration files

public class EmployeeBean
{
    @Autowired
    private DepartmentBean departmentBean;
 
    public DepartmentBean getDepartmentBean(a) {
        return departmentBean;
    }
    public void setDepartmentBean(DepartmentBean departmentBean) {
        this.departmentBean = departmentBean;
    }
    //More code
}
Copy the code
@AutowiredIn the propertiessetterOn the way

When using @AutoWired on setter methods for properties, it is also equivalent to auto-assembly via byType in a configuration file.

public class EmployeeBean
{
    private DepartmentBean departmentBean;
 
    public DepartmentBean getDepartmentBean(a) {
        return departmentBean;
    }
 
    @Autowired
    public void setDepartmentBean(DepartmentBean departmentBean) {
        this.departmentBean = departmentBean;
    }
    //More code
}
Copy the code
@AutowiredOn the constructor

When using @Autowired on a bean constructor, it is also equivalent to auto-assembly via constructor in a configuration file.


package cn.howtodoinjava.autowire.constructor;
 
public class EmployeeBean
{
    @Autowired
    public EmployeeBean(DepartmentBean departmentBean)
    {
        this.departmentBean = departmentBean;
    }
 
    private DepartmentBean departmentBean;
 
    public DepartmentBean getDepartmentBean(a) {
        return departmentBean;
    }
    public void setDepartmentBean(DepartmentBean departmentBean) {
        this.departmentBean = departmentBean;
    }
    //More code
}
Copy the code

@QualifierResolve the conflict

We learned that if we use autowiring in byType mode, the container looks for dependencies in the property class type. If no such type is found, an error is raised. But what if you have two or more beans of the same class type?

In this case, Spring will not be able to select the right bean to inject properties into, so you will need to use the @Qualifier annotation to help the container.

To parse a particular bean, we need to use the @Qualifier annotation as well as the @AutoWired annotation and pass the bean name to the annotation parameter. Consider the following example:

public class EmployeeBean{
    @Autowired
    @Qualifier("finance")
    private DepartmentBean departmentBean;
 
    public DepartmentBean getDepartmentBean(a) {
        return departmentBean;
    }
    public void setDepartmentBean(DepartmentBean departmentBean) {
        this.departmentBean = departmentBean;
    }
    //More code
}
Copy the code

The repeated bean configuration is as follows:

<?xml version="1.0" encoding="UTF-8"? >
<beans>
    <context:annotation-config />
 
    <bean id="employee" class="cn.howtodoinjava.autowire.constructor.EmployeeBean" autowire="constructor">
        <property name="fullName" value="Lokesh Gupta"/>
    </bean>
 
    <! --First bean of type DepartmentBean-->
    <bean id="humanResource" class="cn.howtodoinjava.autowire.constructor.DepartmentBean" >
        <property name="name" value="Human Resource" />
    </bean>
 
    <! --Second bean of type DepartmentBean-->
     <bean id="finance" class="cn.howtodoinjava.autowire.constructor.DepartmentBean" >
        <property name="name" value="Finance" />
    </bean>
</beans>
Copy the code

userequired = falsePerform error-safe auto assembly

Even when you take extra care to auto-assemble Bean dependencies, you may still find strange lookup failures. Therefore, to solve this problem, you will need to make autowage optional so that the application should not throw any exceptions if no dependencies are found and autowage should be ignored.

This can be done in two ways:

  • If you want to make a specificbeanThe nonmandatory specificity of an attributebeanAutomatic assembly is available in@AutowiredUse in annotationsThe required = "false"Properties.
    @Autowired (required=false)
    @Qualifier ("finance")
    privateDepartmentBean departmentBean; `Copy the code
  • If you want to be at the global level (i.e., for allbeanApply optional autowiring; Use the following configuration Settings.
     <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor">
         <property name="requiredParameterValue" value="false" />
     </bean>
     
    Copy the code

Exclude beans from autowiring

By default, autowiring scans and matches all bean definitions in range. If you want to exclude some bean definitions so that they cannot be injected through autowire-candidate, you can do this with autowire-candidate set to false.

  1. useautowire-candidateAs afalseWill be completelybeanExclude candidates for automatic assembly. It’s going to be specificbeanDefinitions are completely excluded from the autowiring infrastructure.
    <?xml version="1.0" encoding="UTF-8"? >
    <beans>
        <context:annotation-config />
     
        <bean id="employee" class="cn.howtodoinjava.autowire.constructor.EmployeeBean" autowire="constructor">
            <property name="fullName" value="Lokesh Gupta"/>
        </bean>
        <! --Will be available for autowiring-->
        <bean id="humanResource" class="cn.howtodoinjava.autowire.constructor.DepartmentBean" >
            <property name="name" value="Human Resource" />
        </bean>
     
        <! --Will not participate in autowiring-->
         <bean id="finance"      class="cn.howtodoinjava.autowire.constructor.DepartmentBean" autowire-candidate="false">
            <property name="name" value="Finance" />
        </bean>
    </beans>
    
    Copy the code
  2. Another approach is based onbeanThe pattern matches the name to restrict autowiring candidates. top<beans/>Elements in thedefault-autowire-candidateProperty accepts one or more properties. For example, you want to restrict the autowage candidate state to nameImplAnything at the endbean, please provide the value* Impl. To provide multiple schemas, define them in a comma-separated list.
     <?xml version="1.0" encoding="UTF-8"? >
     <beans default-autowire-candidates="*Impl,*Dao">
         <context:annotation-config />
      
         <bean id="employee" class="com.howtodoinjava.autowire.constructor.EmployeeBean" autowire="constructor">
             <property name="fullName" value="Lokesh Gupta"/>
         </bean>
         <! --Will be available for autowiring-->
         <bean id="humanResource" class="com.howtodoinjava.autowire.constructor.DepartmentBean" >
             <property name="name" value="Human Resource" />
         </bean>
      
         <! --Will not participate in autowiring-->
          <bean id="finance"      class="com.howtodoinjava.autowire.constructor.DepartmentBean" autowire-candidate="false">
             <property name="name" value="Finance" />
         </bean>
     </beans>
    Copy the code

Note that the value true or false of the autowire-candidate property defined by the bean always takes precedence, and for such beans, pattern matching rules will not apply.

That’s all there is to Spring Bean autowiring.

Spring Bean Autowiring — @AutoWired