Spring Boot 教程

@Lazy 注解

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

@Lazy 注解用来告诉 Spring 是否要延迟初始化指定的Bean。该注解可用于直接或间接用了 @Component 注解的任何类,或用了@Bean注释的方法。

如果 @Component 或 @Bean 定义上不存在 @Lazy 注解,则会进行初始化。如果存在 @Lazy 注解且设置 value为true,则 @Bean或 @Component 定义的 Bean 将不会被初始化,直到被另一个 Bean 引用或从封闭的 BeanFactory 中显式检索。如果存在 @Lazy 且设置 value 为false,则将在执行启动单例初始化的Bean工厂启动时实例化Bean。

如果 @Configuration 类上存在 @Lazy 注解,则表明该 @Configuration 中的所有 @Bean 方法都应延迟初始化。如果在 @Lazy 注解的 @Configuration 类中的 @Bean方法上存在 @Lazy 注解且设置 value 为 false,则表明重写了“默认延迟”行为,并且应立即初始化Bean。

除了 @Lazy 在组件初始化中的作用外,还可以将该注解放置在标有 @Autowired 或 @Inject 的注入点上:在这种情况下,它会为所有受影响的依赖项创建一个惰性解析代理,以替代使用ObjectFactory 或 Provider。

value()

是否应该进行延迟初始化,true 表示开启延迟初始化,false 表示不开启延迟初始化。默认为 true。

示例代码

(1)定义一个 MyConfig 类,该类上面添加了 @Lazy 注解,该注解将延迟该类下的 myBean 初始化,只有当我们用到 MyBean 的时候才会去初始化。如下:

package com.huangx.springboot.springboot_lazy_demo1.config;

import com.huangx.springboot.springboot_lazy_demo1.bean.MyBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

@Configuration
@Lazy
public class MyConfig {

    @Bean
    public MyBean myBean() {
        System.out.println("===> init MyBean");
        return new MyBean("Welcome to SpringBoot.");
    }

}

(2)下面定义了 MyConfig2 类,该类有两个 @Bean 方法,一个返回 MyBena2,另一个返回 ArrayList,其中 myBean2() 方法上面有 @Lazy 注解,表示该 Bean 将延迟初始化。代码如下:

package com.huangx.springboot.springboot_lazy_demo1.config;

import com.huangx.springboot.springboot_lazy_demo1.bean.MyBean2;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

import java.util.ArrayList;

@Configuration
public class MyConfig2 {

    @Bean
    @Lazy
    public MyBean2 myBean2() {
        System.out.println("===> init MyBean2");
        return new MyBean2("Welcome to SpringBoot.");
    }

    @Bean
    public ArrayList arrayList() {
        System.out.println("===> init ArrayList");
        return new ArrayList<>();
    }

}

(3)定义客户端代码,用来调用前面 MyConfig 和 MyConfig2 中定义的 Bean,用来验证 Bean 是否在使用的时候才初始化。代码如下:

package com.huangx.springboot.springboot_lazy_demo1;

import com.huangx.springboot.springboot_lazy_demo1.bean.MyBean;
import com.huangx.springboot.springboot_lazy_demo1.bean.MyBean2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class SpringbootLazyDemo1Application {

    @Autowired
    private ApplicationContext applicationContext;

    public static void main(String[] args) {
        SpringApplication.run(SpringbootLazyDemo1Application.class, args);
    }


    @RequestMapping("/demo1")
    public String demo1() {
        MyBean myBean = applicationContext.getBean(MyBean.class);
        return myBean.getSummary();
    }

    @RequestMapping("/demo2")
    public String demo2() {
        MyBean2 myBean = applicationContext.getBean(MyBean2.class);
        return myBean.getSummary();
    }

}

启动 Spring Boot 程序,通过浏览器分别访问 localhost:8080/demo1 和 localhost:8080/demo2 地址。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号