SpringBoot教程(5)单例Bean懒加载@Lazy的使⽤和失效情况
单例Bean懒加载 @Lazy的使⽤和失效情况
⼀、@Lazy的作⽤
在⽤Spring开发时,我们常⽤的注解修饰的Bean是单实例的,⽐如@Component、@Service、@Bean。
这些单例默认在Spring启动时加载到容器中,以后再调⽤时也不会重新创建,⽽是之间从容器中拿。
@Lazy注解只对单例有⽤,它让Bean在Spring启动时不会加载到容器中,只有在代码⾥第⼀次调⽤时才创建⼀次,加载到容器中,以后再次调⽤时,也只会到容器中拿。
⼆、测试@Lazy在启动时不会创建Bean
1. 先创建简单的类User、Person
@Data
public class User {
private String name;
private int age;
public User(){
System.out.println("初始化:User()");
}
public User(String name,int age){
System.out.println("初始化:User(String name, int age)");
this.name = name;
this.age = age;
}
}
@Data
public class Person {
private String name;
private int age;
public Person(){
System.out.println("初始化:Person()");
}
public Person(String name,int age){
System.out.println("初始化:Person(String name, int age)");
this.name = name;
this.age = age;
}
}
2. 利⽤@Configuration+@Bean创建单例
/**
* 默认@Configuration下@Bean定义的是单实例
* 也就是Spring启动时,就已经加载到Spring容器中了
* @Lazy是延迟加载,只有第⼀次调⽤Bean时才加载到容器中
*/
@Configuration
public class MyConfig {
@Lazy
@Bean(name ="myBeanPerson")
public Person myBeanPerson(){
return new Person("king",31);
}
@Bean(name ="myBeanUser")
public User myBeanUser(){
return new User("king",31);
}
}
运⾏项⽬,只有User的构造器的输出,说明只创建了User的实例
初始化:User(String name,int age)
3. 测试@Lazy修饰的对象的第⼀次创建
@SpringBootApplication
@ComponentScan(value ="info.pigg.study.java")
public class DictApplication {
public static void main(String[] args){
ConfigurableApplicationContext run = SpringApplication.run(DictApplication.class, args);
System.out.println("===Spring启动完毕,测试代码开始===");
Object person01 = Bean("myBeanPerson");
Object person02 = Bean("myBeanPerson");
System.out.println("person01 == person02 : "+(person01 == person02));
Object user01 = Bean("myBeanUser");
Object user02 = Bean("myBeanUser");
System.out.println("user01 == user02 : "+(user01 == user02));
}
输出如下:
初始化:User(String name,int age)
===Spring启动完毕,测试代码开始===
初始化:Person(String name,int age)
person01 == person02 :true
user01 == user02 :true
Person的Bean是懒加载的,Spring启动时不创建,第⼀次调⽤时才创建,以后再调⽤也不创建,直接从容器中拿。
三、@Lazy的失效
对上⾯代码修改,测试失效情况
在User⾥⽤了@Autowired Person myPerson;
@Data
public class User {
@Autowired
Person myPerson;
private String name;
private int age;
public User(){
System.out.println("初始化:User()");
}
public User(String name,int age){
System.out.println("初始化:User(String name, int age)");
this.name = name;
this.age = age;
}
}
运⾏结果如下:
初始化:User(String name,int age)
spring ioc注解初始化:Person(String name,int age)
===Spring启动完毕,测试代码开始===
person01 == person02 :true
user01 == user02 :true
可以看到@Lazy好像失效了,没有起作⽤。
如果只在某个类上添加@Lazy注解,如果⼯程中有其它地⽅依赖了该类,那么即使添加了@Lazy注解,也依然会在IoC容器初始化的时候就去实例化该类。
如果想在使⽤的时候才去实例化,可以在每个依赖该类的地⽅上添加@Lazy注解。例如下⾯代码,Person还是懒加载的。
@Data
public class User {
//添加了@Lazy
@Lazy
@Autowired
Person myPerson;
private String name;
private int age;
public User(){
System.out.println("初始化:User()");
}
public User(String name,int age){
System.out.println("初始化:User(String name, int age)");
this.name = name;
this.age = age;
}
}
还有@DependsOn注解也会让@Lazy失效,具体代码实验看下⾯博客
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论