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();
}

 

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