IOC学习进阶
- @Order
- 使用@Order改变注入顺序
- 实现Ordered接口,重写getOrder方法来改变自动注入顺序
- @DependsOn
- 使用
- @Lazy
- 全局设置-设置所有bean启动时候懒加载
- @Scope
- bean是单例的,会不会有线程安全问题
@Order
可以改变自动注入的顺序
比如有个animal的接口,里面两个实现类 Cat和Dog。这两个都注册为bean。此时注入的时候,就可以用list来进行接收,表示两个都进行注入。
如果还用animal来进行接收,那就会报错,因为@Autowired根据类型找到两个,然后根据名称找,此时找不到就报错
- 类型接口
- animal
public interface Animal {
void eat();
}
- 实现类
- Cat
@Component
public class Cat implements Animal{
@Override
public void eat() {
System.out.println("猫吃老鼠");
}
}
- Dog
@Component
public class Dog implements Animal{
@Override
public void eat() {
System.out.println("狗吃肉");
}
}
- 使用
@Autowired
private List<Animal> animal;
@Test
public void testOrder(){
System.out.println(animal);
}
可以看到先输出Cat,再输出Dog(先注入了Cat,再注入了Dog)
使用@Order改变注入顺序
此时我们可以用@Order注解自定义注入顺序
用法:@Order(数值)—数值小的先注入
让Dog先注入,Cat后注入
@Component
@Order(1)
public class Dog implements Animal{
@Override
public void eat() {
System.out.println("狗吃肉");
}
}
@Component
@Order(2)
public class Cat implements Animal{
@Override
public void eat() {
System.out.println("猫吃老鼠");
}
}
- 测试
可以和上面未加@Order进行对比,加了@Order后Dog先进行了注入
实现Ordered接口,重写getOrder方法来改变自动注入顺序
这种方式了解即可
@Component
@Order(1)
public class Dog implements Animal, Ordered {
@Override
public void eat() {
System.out.println("狗吃肉");
}
@Override
public int getOrder() {
return 1;
}
}
@DependsOn
改变bean的创建顺序
比如下面的 B负责数据库连接,A负责数据库查询,肯定是B先创建bean,此时就可以用@DependsOn进行调整两个bean的创建顺序
使用
- 不加 @DependsOn注解
- A:数据库查询
@Component
public class A {
public A() {
System.out.println("数据库查询");
}
}
- B:数据库连接
@Component
public class B {
public B() {
System.out.println("数据库连接");
}
}
此时可以看到在不加@DependsOn注解的时候,数据库查询bean先创建,明显不对
- 加 @DependsOn注解
因为数据库查询依赖数据库连接所以在数据库查询上加@DependsOn注解
表示:A依赖B,在创建A的时候先创建B
@Component
@DependsOn("b")
public class A {
public A() {
System.out.println("数据库查询");
}
}
- 测试
可以看到,数据库连接先创建,数据库查询后创建
@Lazy
懒加载bean,默认是true:表示懒加载,可以设置成false,表示非懒加载
全局设置-设置所有bean启动时候懒加载
通过配置文件进行设置
@Scope
默认是单例的