spring的注入,可以分为两种,分别是手动注入和自动注入 我们这里要记录的是自动注入
spring的自动注入模型有四种,分别是:
autowire_no(0): 默认的装配模式,如果注入indexBean,没有在属性上加@Autowired或者@Resource,这时候,indexBean是无法注入的autowire_name(1): 通过set方法,并且set方法的名称必须和bean的name名称一致, byNameautowire_type(2): 通过set方法,这种方式set方法可以任意命名,因为是按照set方法的参数类型来注入bean的, byTypeautowire_constructor(3): 通过构造器注入,如果userBean中注入了indexBean,那么必须提供一个带indexBean的构造函数,否则是nullspring默认的自动注入模型,是0,需要通过@Autowired或者@Resource注解注入;如果是非0的,可以不提供这两个注解;
如果我们指定的自动注入模型是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_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将自动注入模型改为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的这种场景