Spring注解驱动开发(五):利用@Lazy实现懒加载


这是我Spring Frame 专栏的第五篇文章,在 Spring注解驱动开发(四):@Bean属性详解(指定Bean初始化和销毁方法)这篇文章中,我向你详细介绍了@Bean注解的各个属性值信息,并且教授了如何高阶定制Bean信息,如果你未读过那篇文章,但是对内容感兴趣的话,我建议你去读一下

1. 背景介绍

Spring在启动时,默认会将非延迟的单实例的bean组件进行初始化,并缓存在Spring Ioc 容器中(我在专栏的上篇文章中介绍了Spring存储单例Bean的容器本质)
综上所述: 单实例bean默认随Spring上下文初始化而初始化

❓ 试想一下,如果我们在容器中定制了大量的Bean,如果一次性的全部初始化,那么容器启动是不是会很慢呢,我们有什么方式可以解决这种问题呢?

这时我们就可以使用@Lazy注解了,它可以实现对某个 bean 的延迟加载(即等待Bean被使用时才进行初始化)

2. 非懒加载模式

我们先来回顾一下非懒加载这种模式:

  1. 我们先自定义一个Person类,之后将它注入容器中
public class Person {
    private Integer id;
    private String name;
    private String sex;
    public Person() {
    }
    public Person(Integer id, String name, String sex) {
        this.id = id;
        this.name = name;
        this.sex = sex;
    }
	// 省略getter,setter,toString方法
}
  1. 接下来我们利用@Configuration+@Bean 向容器中注入Person的一个实例:
@Configuration
public class CustomerConfig {
    /**
     * 向容器中注入Person1 指定初始化和销毁方法
     * @return
     */
    @Bean(name="person1",initMethod = "initMethod",destroyMethod = "destroyMethod")
    public Person person1() {
    	System.out.println("person1 被加载");
        return new Person(1, "jack", "female");
    }
}
  1. 编写测试类,查看person1 加载时机:
public class IcoMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(CustomerConfig.class);
        System.out.println("Ioc 容器初始化完成");
        Person person1 = context.getBean("person1", Person.class);
        System.out.println("person1===>"+person1);
        context.close();
    }
}

在这里插入图片描述


从结果可以看到,单实例bean在Spring容器启动的时候就会被创建,并且被加载到Spring容器中

3. @Lazy 注解实现懒加载

3.1 基本使用

其实实现懒加载模式很简单,只需要在对应的Bean组件上添加@Lazy注解就可以了,我们还是先看一眼 @Lazy 的源码

// Indicates whether a bean is to be lazily initialized.
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Lazy {

	/**
	 * Whether lazy initialization should occur.
	 */
	boolean value() default true;

}

它的源码很简单,只有一个属性,从它的注释可以看到它是用来决定当前Bean是否进行懒加载
接下来我们就来使用 @Lazy 并查看一下效果:

  1. 我们修改 CustomerConfig配置类,在 person1() 上面添加 @Lazy 注解:
@Configuration
public class CustomerConfig {

    /**
     * 向容器中注入Person1 指定初始化和销毁方法
     * @return
     */
    @Lazy
    @Bean(name="person1",initMethod = "initMethod",destroyMethod = "destroyMethod")
    public Person person1() {
        System.out.println("person1 被加载");
        return new Person(1, "jack", "female");
    }
}

2.执行测试类并查看结果:

在这里插入图片描述


从结果可以看到,Ioc 容器初始化时并没有加载 person1,而是等我们使用person1的时候它才被加载
至此,我相信你理解并能使用 @Lazy 注解了

3.2 注意事项

在开篇我就强调了,对单例Bean才能进行懒加载,这意味着对于prototype 类型的Bean并不能实现懒加载,实际上这一点是显而易见的,这里我只是强调一下这件事

4. 总结

这篇文章,我向你介绍了:

  • 什么是懒加载
  • 怎样实现懒加载
  • 懒加载到底什么时候使用
    最后,我希望你看完本篇文章后,能够在适当的时候使用@Lazy注解实现单例Bean的懒加载,也希望你指出我在文章中的错误点,希望我们一起进步,也希望你能给我的文章点个赞,原创不易!

相关文章

学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习...
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面...
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生...
Can’t connect to local MySQL server through socket \'/v...
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 ...
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服...