1. 程式人生 > 程式設計 >簡單瞭解Spring IoC相關概念原理

簡單瞭解Spring IoC相關概念原理

Spring Ioc是Spring框架的基礎,本文會簡單的介紹下Spring Ioc。

Sprong Ioc即控制反轉,它是一種通過描述(在java中可以是XML或註解)並通過第三方去產生或獲取特定物件的方式。

Spring IoC容器

1、Spring IoC容器的設計

Spring IoC容器的設計主要是基於BeanFactory和ApplicationContext這兩個介面,其中ApplicationContext是BeanFactory的一個子介面。也就是說,BeanFactory是Spring IoC容器定義的最底層介面,而ApplicationContext是其高階介面之一,因此大部分情況下會使用後者作為Spring IoC容器。

1.1 ClassPathXmlAppLicationContext

首先我們來認識一下ApplicationContext的子類ClassPathXmlAppLicationContext。先建立一個.xml,程式碼如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
  <bean id="source" class="com.ssm.chapter.pojo.Source">
    <property name="fruit" value="橙汁" />
    <property name="sugar" value="少糖" />
    <property name="size" value="大杯" />
  </bean>
  <bean id="juiceMaker" class="com.ssm.chapter.pojo.JuiceMaker" >
    <property name="beverageShop" value="貢茶" />
    <property name="source" ref="source" />
  </bean>
  </beans>

這裡定義了兩個bean,這樣Spring IoC容器在初始化的時候就可以找到它們,然後使用ClassPathXmlAppLicationContext容器就可以將其初始化,程式碼清單如下:

ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-cfg.xml");
    JuiceMaker juiceMaker = (JuiceMaker) ctx.getBean("juiceMaker");
    System.out.println(juiceMaker.makeJuice());

這樣就會使用Application的實現類ClassPathXmlAppLicationContext去初始化Spring IoC,然後開發者就可以通過Ioc容器獲取資源了。

1.2 Spring Bean的生命週期

Spring IoC容器的本質就是為了管理Bean。生命週期主要是為了瞭解Spring IoC容器初始化和銷燬Bean的過程,通過對它的學習就可以知道如何在初始和銷燬的時候加入自定義的方法,以滿足特定的需求。注:Spring IoC容器初始化和銷燬Bean的過程我這裡就不介紹了啊,在網上很容易找到,這裡主要是通過程式碼去實現生命週期的過程。

除了瞭解生命週期的步驟之外,還要知道生命週期的介面是針對設麼而言的,首先介紹生命週期的步驟:

①如果Bean實現了介面BeanNameAware,那麼就會呼叫setBeanName方法。

②如果Bean實現了介面BeanFactoryAware,那麼就會呼叫setBeanFactory方法。

③如果Bean實現了介面ApplicationContextAware,且Spring IoC容器也是ApplicationContext的一個實現類,那麼就會呼叫setApplicationContext方法。

④如果Bean實現了介面BeanPostProcessor的,那麼就會呼叫postProcessBeforeInitialization方法。

⑤如果Bean實現了介面BeanFactoryPostProcess,那麼就會呼叫afterPropertiesSet方法。

⑥如果Bean自定義了初始化方法,它就會地用用已定義的初始化方法。

⑦如果Bean實現了介面BeanPostProcessor,那麼就會呼叫postProcessAfterInitialization方法,之後這個bean就會完成了初始化,開發者就可以從Spring IoC中獲取Bean的服務。

⑧如果Bean實現了介面DisposableBean,那麼就會呼叫destroy的方法。

⑨如果定義了自定義銷燬方法,那麼就會呼叫它。

此外,上面大部分的介面是針對單個Bean而言的;而BeanPostProcessor介面則是針對所有Bean而言的。為了測試BeanPostProcessor介面,可以寫一個實現類:

package com.ssm.chapter.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class BeanPostProcessorImpl implements BeanPostProcessor {
  @Override
  public Object postProcessBeforeInitialization(Object bean,String beanName) throws BeansException {
    System.out.println("[" + bean.getClass().getSimpleName() + "]物件" + beanName + "開始初始化");
    return bean;
  }

  @Override
  public Object postProcessAfterInitialization(Object bean,String beanName) throws BeansException {
    System.out.println("[" + bean.getClass().getSimpleName() + "]物件" + beanName + "例項化完成");
    return bean;
  }
}

這樣BeanPostProcessor就被我們用程式碼實現了,他會處理Spring IoC容器中的所有Bean。

為了更好的展示生命週期的內容,將上面的程式碼中JuiceMaker類進行修改:

package com.ssm.chapter.pojo;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;


public class JuiceMaker implements BeanNameAware,BeanFactoryAware,ApplicationContextAware,InitializingBean,DisposableBean{

  private String beverageShop = null;

  private Source source = null;

  public String getBeverageShop() {
    return beverageShop;
  }

  public void setBeverageShop(String beverageShop) {
    this.beverageShop = beverageShop;
  }

  public Source getSource() {
    return source;
  }

  public void setSource(Source source) {
    this.source = source;
  }

  public void init() {
    System.out.println("[" + this.getClass().getSimpleName() + "]執行自定義初始化方法");
  }

  public void myDestroy() {
    System.out.println("[" + this.getClass().getSimpleName() + "]執行自定義銷燬方法");
  }

  public String makeJuice() {
    String juice = "這是一杯由" + beverageShop + "飲品店,提供的" + source.getSize() +source.getSugar() +
        source.getFruit();
    return juice;
  }

  @Override
  public void setBeanName(String name) {
    System.out.println("[" + this.getClass().getSimpleName() + "]呼叫BeanNameAware介面的setBeanName方法");
  }

  @Override
  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    System.out.println("[" + this.getClass().getSimpleName() + "]呼叫BeanFactoryAware介面的setBeanFactory方法");
  }

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    System.out.println("[" + this.getClass().getSimpleName() + "]呼叫ApplicationContextAware介面的setApplicationContext方法");
  }

  @Override
  public void destroy() throws Exception {
    System.out.println("[" + this.getClass().getSimpleName() + "]呼叫DisposableBean介面的destroy方法");
  }

  @Override
  public void afterPropertiesSet() throws Exception {
    System.out.println("[" + this.getClass().getSimpleName() + "]呼叫InitializingBean介面的afterPropertiesSet方法");
  }
}

這個類實現了所以生命週期中的方法,以便以觀察生命週期,其中init方法是自定義的初始化方法,而myDestroy方法是自定義的銷燬方法,為了進一步使用這兩個自定義方法,在描述Bean的時候,也要在.xml中進行如下宣告:

<bean id="beanPostProcessor"
     class="com.ssm.chapter.bean.BeanPostProcessorImpl" />
  <bean id="source" class="com.ssm.chapter.pojo.Source">
    <property name="fruit" value="橙汁" />
    <property name="sugar" value="少糖" />
    <property name="size" value="大杯" />
  </bean>
  <bean id="juiceMaker" class="com.ssm.chapter.pojo.JuiceMaker" init-method="init" destroy-method="myDestroy">
    <property name="beverageShop" value="貢茶" />
    <property name="source" ref="source" />
  </bean>

這裡定義了id為JuiceMaker的Bean,其屬性init-menth就是自定義的初始化方法,而destroy-method為自定義的銷燬方法。下面是測試程式碼清單:

 ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring-cfg.xml");
    JuiceMaker juiceMaker = (JuiceMaker) ctx.getBean("juiceMaker");
    System.out.println(juiceMaker.makeJuice());
    ctx.close();

日誌如下:

[Source]物件source開始初始化
[Source]物件source例項化完成
[JuiceMaker]呼叫BeanNameAware介面的setBeanName方法
[JuiceMaker]呼叫BeanFactoryAware介面的setBeanFactory方法
[JuiceMaker]呼叫ApplicationContextAware介面的setApplicationContext方法
[JuiceMaker]物件juiceMaker開始初始化
[JuiceMaker]呼叫InitializingBean介面的afterPropertiesSet方法
[JuiceMaker]執行自定義初始化方法
[JuiceMaker]物件juiceMaker例項化完成
這是一杯由貢茶飲品店,提供的大杯少糖橙汁
[JuiceMaker]呼叫DisposableBean介面的destroy方法
[JuiceMaker]執行自定義銷燬方法

從日誌中可以看出,生命週期中的方法都被執行了。也可以看到BeanPostProcessor針對的是全部Bean。我們也可以自定義初始化和銷燬Bean的方法。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。