亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.430618.com 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

前言

學習過Spring框架的人一定都會聽過Spring的IOC(控制反轉) 這個概念,對于初學Spring的人來說,總覺得IOC是模糊不清的,是很難理解的,今天和大家分享網上的一些技術大牛們對Spring框架的IOC的理解以及談談我對Spring IOC的理解。

讀者福利:私信回復【111】獲取整理好的spring全家桶學習筆記和面試題資料(1184頁PDF文檔)

很多人學Spring框架,總覺得IOC模糊不清?

 

IOC是什么

IOC——Inversion of Control,即“控制反轉”,不是什么技術,而是一種設計思想。在JAVA開發中,IOC意味著將你設計好的對象交給容器控制,而不是傳統的在你的對象內部直接控制。如何理解好IOC呢?理解好IOC的關鍵是要明確“誰控制誰,控制什么,為何是反轉(有反轉就應該有正轉了),哪些方面反轉了”,那我們來深入分析一下:

(1)誰控制誰,控制什么:傳統Java SE程序設計,我們直接在對象內部通過new進行創建對象,是程序主動去創建依賴對象;而IoC是有專門一個容器來創建這些對象,即由Ioc容器來控制對 象的創建;誰控制誰?當然是IoC 容器控制了對象;控制什么?那就是主要控制了外部資源獲?。ú恢皇菍ο蟀ū热缥募龋?。

(2)為何是反轉,哪些方面反轉了:有反轉就有正轉,傳統應用程序是由我們自己在對象中主動控制去直接獲取依賴對象,也就是正轉;而反轉則是由容器來幫忙創建及注入依賴對象;為何是反轉?因為由容器幫我們查找及注入依賴對象,對象只是被動的接受依賴對象,所以是反轉;哪些方面反轉了?依賴對象的獲取被反轉了。

用圖例說明一下,傳統程序設計如圖,都是主動去創建相關對象然后再組合起來:

很多人學Spring框架,總覺得IOC模糊不清?

 

當有了IOC的容器后,在客戶端類中不再主動去創建這些對象了,如圖所示:

很多人學Spring框架,總覺得IOC模糊不清?

 

接下來我們說一下IOC的4個特性

很多人學Spring框架,總覺得IOC模糊不清?

 

1. lazy-Init延遲加載

Bean對象的延遲加載(延遲創建)

ApplicationContext 容器的默認?為是在啟動服務器時將所有 singleton bean 提前進?實例化。提前實例化意味著作為初始化過程的?部分,ApplicationContext實例會創建并配置所有的singleton bean。

1.1 XML方式開啟延遲加載:

lazy-init="" 配置bean對象的延遲加載 ,true或者false false就是立即加載

<bean id="lazyResult" class="com.lagou.edu.pojo.Result" lazy-init="false"></bean>

我們先來看一下當lazy-init="false" 也就是立即加載的時候:

很多人學Spring框架,總覺得IOC模糊不清?

 

可以看到,在容器啟動后,getBean之前,lazyResult這個bean已經存在了。

然后我們把lazy-init="true",設置為true

很多人學Spring框架,總覺得IOC模糊不清?

 

然后我們F8往下走一步:

很多人學Spring框架,總覺得IOC模糊不清?

 

發現出現了lazyResult

1.2 注解開啟延遲加載:

@Lazy

很多人學Spring框架,總覺得IOC模糊不清?

 

1.3全局配置——default-lazy-init="":

在bean的根標簽中:

很多人學Spring框架,總覺得IOC模糊不清?

 

應用場景:

(1)開啟延遲加載?定程度提?容器啟動和運轉性能
(2)對于不常使?的 Bean 設置延遲加載,這樣偶爾使?的時候再加載,不必要從?開始該 Bean 就占?資源

2. FactoryBean和BeanFactory

2.1 BeanFactory

容器的頂級接口,定義了容器的一些基礎行為,負責生產和管理Bean的一個工廠,具體使用它下面的子接口類型,比如ApplicationContext

2.2 FactoryBean

spring中的bean有兩種

  • 普通bean
  • 工廠bean(FactoryBean)
    可以生產某一個類型的bean實例(返回給我們),也就是說我們可以借助于它自定義bean的創建過程。

Bean創建的三種?式中的靜態?法和實例化?法和FactoryBean作?類似,FactoryBean使?較多,尤其在Spring框架?些組件中會使?,還有其他框架和Spring框架整合時使?

//可以讓我們自定義Bean的創建過程,完成復雜bean定義
public interface FactoryBean<T> {
 //返回FactoryBean創建的實例,如果isSingleton返回true,則該實例會放到Spring容器的單例緩存池中Map
 @Nullable
 T getObject() throws Exception;

    //返回FactoryBean創建的bean類型
 @Nullable
 Class<?> getObjectType();

 //返回作用域是否單例
 default boolean isSingleton() {
  return true;
 }
}

2.2.1 新建類CompanyFactoryBean,實現FactoryBean接口,并重寫方法:

public class CompanyFactoryBean implements FactoryBean<Company> {
    private String companyInfo;//注入公司名稱,地址,規模  以逗號分隔

    public void setCompanyInfo(String companyInfo) {
        this.companyInfo = companyInfo;
    }

    @Override
    public Company getObject() throws Exception {
        //創建復雜對象Company
        Company company=new Company();
        String[] split = companyInfo.split(",");
        company.setName(split[0]);
        company.setAddress(split[1]);
        company.setScale(Integer.parseInt(split[2]));

        return company;
    }

    @Override
    public Class<?> getObjectType() {
        //返回bean的類型
        return Company.class;
    }

    @Override
    public boolean isSingleton() {
        //是否是單例
        return true;
    }
}

public class Company {
    private String name;
    private String address;
    private int scale;
 //省略getset 和toString
}

2.2.2 xml文件中配置bean

<bean id="companyBean" class="com.lagou.edu.factory.CompanyFactoryBean">
   <property name="companyInfo" value="拉鉤,中關村,500"></property>
</bean>

2.2.3 測試

    @org.junit.Test
    public void test(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Object companyBean = applicationContext.getBean("companyBean");
        System.out.println(companyBean);
    }
//結果返回的是 Company{name='拉鉤', address='中關村', scale=500}   

雖然在xml配置文件中配置的bean的class="com.lagou.edu.factory.CompanyFactoryBean" 但是返回的Company類型。

如何返回CompanyFactoryBean類型呢?

很多人學Spring框架,總覺得IOC模糊不清?

 


打印結果為:com.lagou.edu.factory.CompanyFactoryBean@545b995e

3. 后置處理器

Spring提供了兩種后處理bean的擴展接?,分別為 BeanPostProcessor 和BeanFactoryPostProcessor,兩者在使?上是有所區別的。

??初始化(BeanFactory)—> Bean對象

在BeanFactory初始化之后可以使?BeanFactoryPostProcessor進?后置處理做?些事情

在Bean對象實例化(并不是Bean的整個?命周期完成)之后可以使?BeanPostProcessor進?后置處理做?些事情

注意:對象不?定是springbean,?springbean?定是個對象

3.1 SpringBean生命周期圖

很多人學Spring框架,總覺得IOC模糊不清?

 

按照上述描述的打印一下??纯词欠褚恢拢?/p>

//實現了BeanNameAware、BeanFactoryAware、ApplicationContextAware、InitializingBean,DisposableBean接口
public class Result implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {
    private String status;
    private String message;
 //省略getset toString方法

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("4.BeanFactoryAware:"+beanFactory);
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("3.BeanNameAware:"+name);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("5.ApplicationContextAware:"+applicationContext);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("7.InitializingBean");
    }

    public void initMethodTest(){
        System.out.println("8.initMethod");
    }

    @PostConstruct
    public void postCoustrcut(){
        System.out.println("postCoustrcut");
    }

    //銷毀之前執行
    @PreDestroy
    public void preDestroy(){
        System.out.println("銷毀之前執行");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("DisposableBean");
    }
}

/**
    攔截實例化之后的對象(實例化了 并且屬性注入了)
    攔截所有的
 */
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if ("lazyResult".equalsIgnoreCase(beanName)){
            System.out.println("MyBeanPostProcessor before");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if ("lazyResult".equalsIgnoreCase(beanName)){
            System.out.println("MyBeanPostProcessor After");
        }
        return bean;
    }
}

//XML配置文件中:    
<bean id="lazyResult" class="com.lagou.edu.pojo.Result"  init-method="initMethodTest"></bean>

//測試:
    @org.junit.Test
    public void testBeanLazy(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        Object lazyResult =  applicationContext.getBean("lazyResult");
        System.out.println(lazyResult);
        applicationContext.close();
    }

打印出:

很多人學Spring框架,總覺得IOC模糊不清?

 

4. 其他:

很多人學Spring框架,總覺得IOC模糊不清?

分享到:
標簽:Spring
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定