目录
- 第一步存 Bean
- 第二步获取并使用 Bean
- 依赖查找的方式
- ApplicationContext vs BeanFactory
- 更简单的存储 Bean
- 1. 配合五大类注解使用
- 2. 方法上添加注解 @Bean
- 更简单的获取 Bean
Spring IoC 容器管理的资源就是对象,这个对象也叫做 Bean。Spring 作为一个 IoC 容器,最基础的功能就是将对象存储到容器里以及从容器中拿对象。
DI 依赖注入,就在程序运行期间,动态的将依赖对象获取到的过程就是依赖注入。
IoC 与 DI:描述的都是同一件事,就是我们当前程序的运行需要另一个对象的时候我们不需要在手动创建这个对象,而是从框架中直接获取,然后注入到当前程序。 其实本质就是对象的这个生命周期交给框架来控制而不是当前程序或者说开发者的代码。区别就是IoC是一种设计思想,而 DI 就是这个思想的一种具体实现方式。
第一步存 Bean
此时 UserService 这个对象就已经存储到 容器中了。
第二步获取并使用 Bean
依赖查找的方式
ApplicationContext vs BeanFactory
- ApplicationContext 是 BeanFactory 的一个子类(间接子类),ApplicationContext 拥有更多的功能
- 加载 Bean 的机制不同:
BeanFactory 是懒加载,按需加载,也就是使用一个 Bean,加载一个 Bean
ApplicationContext 一次性加载所有的 Bean 对象
更简单的存储 Bean
1. 配合五大类注解使用
2. 方法上添加注解 @Bean
注意,@Bean 必须配合五大类注解一起使用。
名字默认是 方法名,不是要获取的对象名。
@Bean 可以重命名:name 和 value 都可以修改名称,支持多个名称。需要注意的是,重命名之后,使用方法名就不能获取到对象了。
更简单的获取 Bean
对象装配有 3 种方式
- 属性注入
@Autowired 注解即可
属性注入的对象如果在框架中存了多个,就会报这个错,解决方案:
- 将对象名字修改成 存的时候对应的某一个名字
使用注解 @Qualifier
优点:用起来简单
缺点:- 无法注入 final 修饰的对象
此时有两种方法解决,一种是直接 new 一个对象,另一种是在 构造方法里 new。 - 只适用于 IoC 容器
- 更容易违背单一设计原则,因为使用起来比较简单
- 构造方法注入
Spring 4.x 推荐的方式
@Autowired 按道理来讲应该是要加的,但是构造方法注入可以不加,或者说不加也行,当然不加的话有一个前提就是只有一个构造方法。
优点:
- 可以注入不可变对象
- 注入的对象不会被修改,因为构造方法只会加载一次
- 注入的对象会被完全初始化
- 通用性更好
缺点:官方没有提。 - 麻烦
- 不能解决循环依赖问题
- Setter 注入
优点:通常 set 只 set 一个属性,所以 setter 更符合单一设计原则
缺点:
- 无法注入一个 final 修饰的属性
- setter 注入的对象可以被修改
还有一点补充就是这里的 @Autowired 可以替换成 @Resource 注解,效果是一样的,除了 构造方法不支持@Resource。
这两个注解的区别:
- @Autowired 是 Spring 的, @Resource 是 jdk 的
- 由于 Spring 框架执行在 java 之后,所以有的情境下使用 @Autowired 会报错(误报,用还是能用的),类似于后到教室不知道前面老师讲了什么一样。
- 相比于 @Autowired 来说,@Resourse 支持更多的参数设置(比如可以通过设置 name 解决相同 Bean 注入问题)
- @Resource 不支持 构造方法注入