spring bean懒加载

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/neweastsun/article/details/78763954

spring bean懒加载

使用spring,则所有bean统一交给spring管理,spring负责初始化、销毁等整个声明周期。所有bean的定义通过配置文件或javaConfig方式。启动时统一初始化并加载至spring的applicationContext中,通过其getBean方法获取。

但有时为了加快系统启动速度,并不需启动时立刻初始化并加载,可以在使用其时才初始化并加载。本文通过示例进行说明。

环境准备

使用gradle和idea,这里直接给出build.gradle文件内容。使用maven自己对照修改下。
使用spring及test相关依赖。

build.gradle

group 'com.dataz'
version '1.0-SNAPSHOT'

apply plugin: 'idea'
apply plugin: 'java'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
    maven { url 'http://maven.springframework.org/release' }
    maven { url 'http://download.java.net/maven/2' }
    maven { url 'https://plugins.gradle.org/m2/' }
}

dependencies {
    // 日志依赖
    compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.7.21'

    compile group: 'org.springframework', name: 'spring-beans', version: '5.0.1.RELEASE'
    compile group: 'org.springframework', name: 'spring-context', version: '5.0.1.RELEASE'

    testCompile group: 'org.springframework', name: 'spring-test', version: '5.0.1.RELEASE'
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

示例bean

ConfigBean有init方法和destory方法。还有布尔型isInitialized public静态属性。如果初始化完成其值为true。

ConfigBean.java

package com.dataz.entity;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ConfigBean {
    private Logger logger = LoggerFactory.getLogger(ConfigBean.class);

    private String value;
    public static boolean isInitialized;

    public ConfigBean(){
        isInitialized = true;
    }

    public ConfigBean(String value){
        this();
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public void destroy() {
        logger.info("destroy called for ConfigBean({})",value);
    }

    public void init() {
        logger.info("init called for ConfigBean({})",value);
    }

    public String toString() {
        return String.format("ConfigBean: value[ %s ]",value);
    }
}

spring bean配置

这里使用javaConfig方式配置。通过@Configuration注解,spring会自动识别并加载,与xml配置功能一致。

SysConfig.java
@lazy注解让该ConfigBean延迟加载,同时指定其初始化和销毁方法。

SysConfig.java

package com.dataz;

import com.dataz.entity.ConfigBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

@Configuration
public class SysConfig {

    @Bean(initMethod = "init",destroyMethod = "destroy")
    @Lazy
    public ConfigBean configBean(){
        return new ConfigBean("A");
    }
}

加载测试

context.getBean()调用之前,可以看到configBean没有初始化,调用之后初始化成功。读者可以尝试注释@Lazy,对比查看结果。

ConfigBeanTest.java

package com.dataz.entity;

import com.dataz.SysConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=SysConfig.class)
public class ConfigBeanTest {
    private Logger logger = LoggerFactory.getLogger(ConfigBeanTest.class);

    @Autowired
    private ApplicationContext context;

    private ConfigBean configBean;

    @Test
    public void lazyTest(){
        logger.info("configBean init flag:{}",ConfigBean.isInitialized);
        ConfigBean.isInitialized = false;

        logger.info("bean lazy load...............");

        logger.info("configBean :{}",context.getBean("configBean"));
        logger.info("configBean init flag:{}",ConfigBean.isInitialized);
    }
}

输出结果:

com.dataz.entity.ConfigBeanTest - configBean init flag:false
com.dataz.entity.ConfigBeanTest - bean lazy load...............
com.dataz.entity.ConfigBean - init called for ConfigBean(A)
com.dataz.entity.ConfigBeanTest - configBean :ConfigBean: value[ A ]
com.dataz.entity.ConfigBeanTest - configBean init flag:true
o.s.c.s.GenericApplicationContext - Closing 
com.dataz.entity.ConfigBean - destroy called for ConfigBean(A)

总结

本文通过javaConfig方式测试spring懒加载。xml配置方式通过default-lazy-initlazy-init 属性,前者统一指定,后者在bean定义时指定,与@lazy对应。那么通过注解方式可以统一指定默认懒加载吗?当然也可以,@lazy可以直接用在@bean或@Component定义的类上,也可以使用在 @Configuration定义类上,后者表示该类中所有@Bean方法对应类被懒加载,与default-lazy-init 功能一致。

展开阅读全文

没有更多推荐了,返回首页