spring注入方式有两种: 1 通过set方法 2 通过构造函数(如果有多个构造函数会选择参数多的构造方法)
自动装配技术(手动装配):
@Resource: 默认是通过name来查找注入值,如果不存在就报错
@Autowired 通过类型查找(类型),然后再通过name
以上两种通过反射,然后设置值
AutowireMode(自动装配模型):在spring中有四种模式分别是:
1 autowire_no(0): 默认装配模式, 目前非xml配置都是使用这种方式,然后程序员使用注解手动注入
2 autowire_name: 通过set方法,并且 set方法的名称需要和bean的name一致 byName
3 autowire_type: 通过set方法,并且再根据bean的类型,注入属性,是通过类型配置 byType
4 autowire_construcor: 通过构造器注入
下面详细讲解
/**
* Constant that indicates no autowiring at all.
* @see #setAutowireMode
* 默认的装配模式: 这种方式bean无法注入 只有个通过其他方式才能注入,比如人为set,加@Resource或@Autoried
*/
1 public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
代码如下:
1 首先自定义一个bean注册器,用来设置bean属性的注入方式
public class MyImportBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
GenericBeanDefinition son =
(GenericBeanDefinition)registry.getBeanDefinition("son");
//设置装配模型
//设置auto类型: AUTO_NO 默认是程序要经常加的 @Autowried或者@Resource
//设置Son这个类的属性注入方式为默认类型
son.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_NO);
registry.registerBeanDefinition("son",son);
}
}
2 定义Son这个类
public class Son {
//不做任何处理,这个时候很明显Son对象里面student是空的
private Student student;
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
}
3 测试类:
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new
AnnotationConfigApplicationContext();
applicationContext.register(MyBean.class);
applicationContext.register(Appconfig.class);
applicationContext.refresh();
/* 1 不加 @Autowired或者@Resource 不做特殊处理
* 下面这对象会为空
* 2 写个类实现ImportBeanDenitionRegester, 设置Son属性的注入方式
MyImportBeanDefinitionRegister
*
*
* */
System.out.println("==="+applicationContext.getBean(Son.class).getStudent());
}
}
这个时候很显然结果是null,如果你想student的值不为空,那么你可以在 student 上面加注解@Autowired或者@Resource
所以说默认类型是spring是不会帮你做属性值注入的,目前程序员编写的bean都是这个模式,所以我们都是加@Autowired或者@Resource
下面的例子测试可以使用上面的代码测试,这里就不重复写了
/**
* Constant that indicates autowiring bean properties by name.
* @see #setAutowireMode
* 这种是通过属性的名字来注入,不过需要提供set方法,如果没有提供set方法也是空
* 在student 上面可以不加注解 @Autowried或者@Resource
* setAAA(Student student) ,set方法名 AAA只能是和类Student名相同,否则无法注入,
* 原理: spring 根据AAA区spring容器中查找是否有名称为AAA的类,如果有就通过setAAA方法注入进入,否则就为空
* 和属性名无关
* 通过set方法注入
* byName 通过名字
*/
2 public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
/**
* Constant that indicates autowiring bean properties by type.
* @see #setAutowireMode
* 通过属性类型来注入值: 同时也是通过set方法来赋值的,如果没有提供set方法也是空
* 在student 上面可以不加注解 @Autowried或者@Resource
* setAAA(Student student) 只需要是Student类型即可,set方法名可以随便取
* byType 通过类型注入
*/
3 public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
/**
* Constant that indicates autowiring a constructor.
* @see #setAutowireMode
* 通过构造器注入:如果没有通过@Autowried或者@Resource注解的话,Spring只能通过在Son中的构造器中才能给student赋 上值
*/
4 public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
所以说呢spring中的AutowireMode(自动装配模型)并不是我们说的自动状态技术,平时说的自动转配技术要么是
byType和byName,。
综合上面讲的自动状态模型只能通过set方法和构造方法来注入值,但是@Resource,@Autowired的不是通过set方法来注入值的
这也是他们之间的区别。