Spring automatically injects the model

Spring injection can be divided into two types, manual injection and automatic injection.
What we want to record here is automatic injection.

Automatic model injection

There are four spring automatic injection models, namely:

  • autowire_no(0): The default assembly mode. If indexBean is injected, @Autowired or @Resource is not added to the attribute. At this time, indexBean cannot be injected
  • autowire_name(1): through the set method, and the name of the set method must be consistent with the name of the bean, byName
  • autowire_type(2): Through the set method, the set method can be named arbitrarily in this way, because the bean is injected according to the parameter type of the set method, byType
  • autowire_constructor(3): Inject through the constructor, if indexBean is injected into userBean, then a constructor with indexBean must be provided, otherwise it is null

The default automatic injection model of spring is 0, which needs to be injected through @Autowired or @Resource annotations; if it is non-zero, these two annotations may not be provided;

application

autowire_name

If the automatic injection model we specify is autowire_byname, then we only need to provide the set method, and the method name of the set method must be the value of the injected attribute, otherwise it will not be injected

@Component
public class IndexBean {
    
    
}

@Component
public class UserBean {
    
    

    private IndexBean indexBean;

    public void setIndexBean123(IndexBean indexBean) {
    
    
        System.out.println("通过set方法注入属性");
        this.indexBean = indexBean;
    }

    public void setIndexBean(IndexBean indexBean){
    
    
        System.out.println("空参setIndex方法执行");
        this.indexBean = indexBean;
    }

    public void test() {
    
    
        System.out.println("注入的indexBean属性是:" + indexBean);
    }
}	

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
    
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory)
            throws BeansException {
    
    
        GenericBeanDefinition userBean = (GenericBeanDefinition) configurableListableBeanFactory
                .getBeanDefinition("userBean");
        System.out.println("默认的autowireMode是:" + userBean.getAutowireMode());
        userBean.setAutowireMode(1);
    }
}

The MyBeanFactoryPostProcessor here is a beanFactoryPostProcessor implementation class I customized. Here I try to modify the automatic injection model of beanDefinition. This is related to the mechanism of spring initialization. I have detailed the execution order of spring converting beans into beanDefinitions.

Here I set the automatic injection model to 1, which is autowire_byname; in this case, when injecting properties in the bean, there is no need to provide annotations such as @Autowired, @Resource, etc.

When the above code is executed, it executes the setIndexBean() method in UserBean,

public class AutowireModeTest {
    
    
    public static void main(String[] args) {
    
    
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AutowiredModelConfig.class);
        UserBean userBean = ac.getBean(UserBean.class);
        userBean.test();
    }
}
执行结果:
空参setIndex方法执行
注入的indexBean属性是:com.spring.study.autowiremode.IndexBean@1622f1b

autowire_type

If the automatic injection model we specify is autowire_tyoe, then only the set method needs to be provided. The method name can be arbitrary, but it should start with set, and the parameter of the set method must be the type to be injected

I only add the above

userBean.setAutowireMode(1);改为userBean.setAutowireMode(2);

At this time, the automatic injection model of userBean is byType. When it is executed again, two set methods will be called in turn. Because the two set methods I provided, although the names are different, the input parameters are indexBean, so this It also explains that you only need to ensure that the parameter of the set method is of type indexBean, and the method name starts with set. It does not matter whether it is setA, or setB, or setC.

Results of the

空参setIndex方法执行
通过set方法注入属性
注入的indexBean属性是:com.spring.study.autowiremode.IndexBean@e056f20

autowire_constructor

Change the automatic injection model to 3, and then increase the parameterless constructor and the parameterized constructor in UserBean respectively

@Component
public class UserBean {
    
    

    private IndexBean indexBean;

    public UserBean(IndexBean indexBean) {
    
    
        System.out.println("userBean带参构造函数");
        this.indexBean = indexBean;
    }

    public UserBean(){
    
    
        System.out.println("userBean空参构造函数");
    }

    public void setIndexBean123(IndexBean indexBean) {
    
    
        System.out.println("通过set方法注入属性");
        this.indexBean = indexBean;
    }

    public void setIndexBean(IndexBean indexBean){
    
    
        System.out.println("空参setIndex方法执行");
        this.indexBean = indexBean;
    }

    public void test() {
    
    
        System.out.println("注入的indexBean属性是:" + indexBean);
    }
}

The execution result at this time is:

userBean带参构造函数
注入的indexBean属性是:com.spring.study.autowiremode.IndexBean@78b66d36

in conclusion

The above code can fully prove that if the auto-injection model is set to any one of 1, 2, and 3, there is no need to provide @Autowired or @Resource annotations. The @Autowired we understood before is to search according to the type first, and then according to Name search, this statement is only for the scenario where autowireMode is 0

Guess you like

Origin blog.csdn.net/CPLASF_/article/details/109187921