spring自动注入模型

spring的注入,可以分为两种,分别是手动注入和自动注入
我们这里要记录的是自动注入

自动注入模型

spring的自动注入模型有四种,分别是:

  • autowire_no(0): 默认的装配模式,如果注入indexBean,没有在属性上加@Autowired或者@Resource,这时候,indexBean是无法注入的
  • autowire_name(1): 通过set方法,并且set方法的名称必须和bean的name名称一致, byName
  • autowire_type(2): 通过set方法,这种方式set方法可以任意命名,因为是按照set方法的参数类型来注入bean的, byType
  • autowire_constructor(3): 通过构造器注入,如果userBean中注入了indexBean,那么必须提供一个带indexBean的构造函数,否则是null

spring默认的自动注入模型,是0,需要通过@Autowired或者@Resource注解注入;如果是非0的,可以不提供这两个注解;

应用

autowire_name

如果我们指定的自动注入模型是autowire_byname的话,那只需要提供set方法即可,并且set方法的方法名必须是注入属性的值,否则会无法注入

@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);
    }
}

这里的MyBeanFactoryPostProcessor是我自定义的一个beanFactoryPostProcessor实现类,在这里尝试修改beanDefinition的自动注入模型,这个和spring初始化的机制有关系,在前面有详细说过spring将bean转换为beanDefinition的执行顺序

我这里将自动注入模型设置为1,也即autowire_byname;那这样的话,在bean中注入属性的时候,就无需提供@Autowired、@Resource等这些注解

上面的代码在执行的时候,执行的是UserBean中的setIndexBean()方法,

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

如果我们指定的自动注入模型是autowire_tyoe的话,那也是只需要提供set方法即可,方法名可以随意,但是要以set开头,set方法的参数必须是要注入的类型

我只将上面的

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

这时候,userBean的自动注入模型就是byType,那再次执行的时候,是会依次调用两个set方法,因为我提供的两个set方法,虽然名字不一样,但是入参都是indexBean,所以,这也说明了,只需要确保set方法的参数是indexBean类型即可,方法名以set开头,具体是setA,还是setB,还是setC都无所谓

执行结果

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

autowire_constructor

将自动注入模型改为3,然后在UserBean中分别提高无参构造函数和带参构造函数

@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);
    }
}

此时的执行结果是:

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

结论

以上代码,可以充分证明,如果将自动注入模型设置为1、2、3其中任意一个值,就无须再提供@Autowired或者@Resource注解,我们之前所理解的@Autowired是先根据类型查找,再根据name查找,这个说法,只是针对autowireMode是0的这种场景

猜你喜欢

转载自blog.csdn.net/CPLASF_/article/details/109187921