Spring IoC (ApplicationContext) 容器一般都会在启动的时候实例化所有单实例 bean 。如果我们想要 Spring 在启动的时候延迟加载 bean,即在调用某个 bean 的时候再去初始化,那么就可以使用 @Lazy 注解。

@Lazy 的属性

value 取值有 true 和 false 两个 默认值为 true

true 表示使用 延迟加载, false 表示不使用,false 纯属多余,如果不使用,不标注该注解就可以了。
Person 类

  1. public class Person {
  2. private String name;
  3. private Integer age;
  4. public Person() {
  5. }
  6. public Person(String name, Integer age) {
  7. System.out.println(" 对象被创建了.............");
  8. this.name = name;
  9. this.age = age;
  10. }
  11. // 省略 getter setter 和 toString 方法
  12. }

配置类 不标注 @Lazy 注解

  1. public class LazyConfig {
  2. @Bean
  3. public Person person() {
  4. return new Person("李四", 55);
  5. }
  6. }

测试

  1. @Test
  2. public void test5() {
  3. ApplicationContext ctx = new AnnotationConfigApplicationContext(LazyConfig.class);
  4. }

不获取 bean , 看控制台是否会打印。如果有打印,代表调用了构造器。

结果

@Lazy注解简析 - 图1

在配置类打上 @Lazy 注解

  1. public class LazyConfig {
  2. @Lazy
  3. @Bean
  4. public Person person() {
  5. return new Person("李四", 55);
  6. }
  7. }

再来看输出结果

@Lazy注解简析 - 图2T

没有打印语句,对象没有调用构造器,那么方法也就没有被创建。
@Lazy(value = false) 或者 @Lazy(false) 那么对象会在初始化的时候被创建

@Lazy注解注解的作用主要是减少springIOC容器启动的加载时间

当出现循环依赖时,也可以添加@Lazy

spring使用@Autowired为抽象父类注入依赖

有时候为了管理或者避免不一致性,希望具体服务统一继承抽象父类,同时不同子类具体服务使用@Autowired为抽象父类注入不同的子类依赖。

经仔细研究与测试,只要父类要注入的属性是protected保护级别即可,如下:

父类:

  1. public class Father {
  2. @Lazy
  3. @Autowired
  4. protected Person p;
  5. }

子类:

  1. @Configuration
  2. public class Son extends Father{
  3. @Bean("p1")
  4. public Person getPerson(){
  5. return new Person(1);
  6. }
  7. }
  1. @Configuration
  2. public class Son2 extends Father{
  3. @Bean("p2")
  4. public Person getPerson(){
  5. return new Person(2);
  6. }
  7. }

注意,@Bean默认使用方法名作为bean名称,这里要指定名称,防止冲突。

测试:

  1. @SpringBootTest(classes = DemoApplication.class)
  2. @RunWith(SpringRunner.class)
  3. @FixMethodOrder(MethodSorters.NAME_ASCENDING)
  4. public class FatherTest {
  5. @Autowired
  6. private Son s1;
  7. @Autowired
  8. private Son2 s2;
  9. @Test
  10. public void test(){
  11. System.out.println(s1.getPerson().getAge());
  12. System.out.println(s2.getPerson().getAge());
  13. }
  14. }

结果:

  1. 2021-08-12 15:58:08.769 INFO 12160 --- [ main] com.example.lazy.FatherTest : Started FatherTest in 4.715 seconds (JVM running for 5.61)
  2. 1
  3. 2