懒加载Bean(Lazy-initialized Beans)的概念其实很简略,就是通过设置,Spring IoC容器在初始化的过程中不对单例Bean进行实例化,而默认状况下会。
默认状况下Spring IoC容器初始化的过程中会创立所有的单例Bean,“创立”的步骤包含实例化、以及实例化之后的属性填充,以及其余可能的前置后置操作(各种beanpostprocessor),都会被调用。
个别状况下这种提前实例化也是必要的,因为提前实例化能够在系统启动的过程中执行,能够提前裸露实例创立以及依赖注入的谬误。而懒加载则不同,这类谬误须要在Bean被调用的时候能力裸露,而Bean被调用很可能是在系统启动之后的某一时刻,很可能是在系统升级上线的几天之后了。
懒加载能够通过xml配置文件指定:
<bean id="lazy" class="com.something.ExpensiveToCreateBean" lazy-init="true"/><bean name="not.lazy" class="com.something.AnotherBean"/>
也能够通过@Lazy注解指定。
咱们对后面的用例简略批改验证一下懒加载。首先批改DependencyB,减少无参结构器,打印一句话:
public DependencyB(){ System.out.println("This is DependencyB constructor running..."); }
同样,DependencyA也减少结构器:
public DependencyA(){ System.out.println("This is DependencyA constructor running..."); }
而后批改启动类,只初始化Spring,不获取Bean:
public class App { public static void main(String[] args) { ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfiguration.class); System.out.println("I am Ok...");}
执行启动类:
This is DependencyB constructor running...This is DependencyA constructor running...I am Ok...
尽管没有从Spring IoC容器获取Bean,然而能够看到DependencyB和DependencyA都被实例化了。
上面首先批改DependencyA,懒加载:
@Service@Primary@Scope("prototype")@Lazypublic class DependencyA implements IDependencyA { @Override public void test(){ System.out.println("I am DependencyA test..."); } public DependencyA(){ System.out.println("This is DependencyA constructor running..."); }}
执行启动类:
This is DependencyB constructor running...This is DependencyA constructor running...I am Ok...
竟然没有起作用???
再批改DependencyB试试:
I am Ok...
批改DependencyB为懒加载后,失效了,执行启动类后发现DependencyB和DependencyA都没有被实例化。
以上DependencyA懒加载设置有效的起因:懒加载和依赖关系无关,如果一个懒加载的BeanA被另外一个非懒加载的单例BeanB依赖的话,那么BeanA的懒加载设置会生效,因为BeanB作为单例Bean在Spring IoC初始化的过程中会被实例化,他所依赖的对象BeanA也必须被实例化以确保BeanB的可用性。
集体感觉懒加载的实用性不太强,个别状况下咱们应用Spring的默认设置就好。
上一篇 Spring FrameWork从入门到NB -Bean Scopes