Spring懒加载与非懒加载以及Scope作用域

Spring默认为非懒加载(即在项目启动时——Spring容器初始化过程中加载)

Spring设置为非懒加载时,项目(Spring容器:ApplicationContext)启动时立刻初始化,Spring容器会把所有的扫描包下的带Spring注解(@Component、@Repository、@Service、@Controller)或者通过Spring xml配置的bean全都初始化。Spring容器初始化时,会调用默认构造方法,如果类中没有默认的无参构造方法,那么Spring初始化时会报错误。

以下两点需要同学们注意:

  • 由于在controller中会注入service层的类,由于,controller层面上的spring-mvc不是懒加载,即当在controller中注入service时,就会初始化此service类。因此即调用到谁初始化谁。
  • 如果一个单例bean被设置为懒加载,而另一个非懒加载的单例bean依赖于它,那么当ApplicationContext提前实例化单例bean时,它必须也确保所有上述bean也被预先初始化,当然也包括设置为懒加载的bean,即被非懒加载的bean依赖时懒加载的bean也会被初始化。

Spring懒加载配置方式:

  • lazy-init=“true”:懒加载
  • lazy-init=“false”:非懒载
  • lazy-init=“default”:懒加载

示例代码如下:

<bean id="test1" class="cn.java.ioc1.YelloMouseWolf" lazy-init="default"></bean>

懒加载与非懒加载的优缺点如下

懒加载:

优点:对象使用的时候才去创建,节省资源。

缺点:不利于提前发现错误。

非懒加载:

优点:利于提前发现错误。

缺点:容器启动的时候立刻创建对象。消耗资源。

当scope=“prototype” (多例——原型)时,默认以懒加载的方式产生对象。

当scope=“singleton” (单例)时,默认以非懒加载的方式产生对象。Spring的Scope(作用域)默认为Singleton(单例)。

注:当Singeton的bean当中引用了一个ProtoType的bean时,由于Singleton的bean只会初始化一次,所以作用域为ProtoType的bean不会被重新初始化,永远会是同一个bean。Spring提供的解决方法可参考如下代码

方法一:实现Spring的ApplicationContextAware接口

package com.tyyd.ioc.autowire.dao.impl;

import com.tyyd.ioc.autowire.dao.PigDao;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;

@Repository
@Scope("prototype")
public class PigDaoImpl implements PigDao {
    public void test() {
        System.out.println("PigDao");
    }
}
package com.tyyd.ioc.autowire.service.impl;

import com.tyyd.ioc.autowire.dao.PigDao;
import com.tyyd.ioc.autowire.service.PigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class PigServiceImpl implements PigService, ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Autowired
    private PigDao pigDao;

    public void test() {
        System.out.println("PigServiceImpl: " + this.hashCode());
        System.out.println("PigDaoImpl: " + applicationContext.getBean("pigDaoImpl").hashCode());
    }

    public void setPigDao(PigDao pigDao) {
        this.pigDao = pigDao;
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
package com.tyyd.ioc.test;

import com.tyyd.ioc.autowire.config.JavaConfig;
import com.tyyd.ioc.autowire.service.impl.PigServiceImpl;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(JavaConfig.class);
        PigServiceImpl pigService = (PigServiceImpl)annotationConfigApplicationContext.getBean("pigServiceImpl");
        pigService.test();
    }
}

方法二:通过注解@Lookup实现(相同代码不做重复展示)

package com.tyyd.ioc.autowire.service.impl;

import com.tyyd.ioc.autowire.dao.PigDao;
import com.tyyd.ioc.autowire.service.PigService;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

@Service
public class PigServiceImpl implements PigService {

    public void test() {
        System.out.println("PigServiceImpl: " + this.hashCode());
        System.out.println("PigDaoImpl: " + getPigDao().hashCode());
    }

    @Lookup
    public PigDao getPigDao() {
        return null;
    }
}

方法三:同样通过注解@Lookup

package com.tyyd.ioc.autowire.service.impl;

import com.tyyd.ioc.autowire.dao.PigDao;
import com.tyyd.ioc.autowire.service.PigService;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

@Service
public abstract class PigServiceImpl implements PigService {

    public void test() {
        System.out.println("PigServiceImpl: " + this.hashCode());
        System.out.println("PigDaoImpl: " + getPigDao().hashCode());
    }

    @Lookup
    public abstract PigDao getPigDao();
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章