(001)Spring 之 IOC及其容器

概述

Spring的最終模板是簡化應用開發的編程模型。spring用於替代更加劇量級的企業級java技術,如EJB(Enterprise JavaBean)。html

爲了下降Java開發的複雜度。spring採起了如下4中關鍵策略:java

  • 基於POJO(Plain Ordinary Java Objects,實際上就是普通的java類)的輕量級和最小侵入式編程。
  • 經過依賴注入(DI, Dependency Injection)和麪向接口編程實現鬆耦合。
  • 基於切面(AOP, Aspect Oriented Programming)和慣例(能夠理解爲默認配置、方式)進行聲明式編程。
  • 經過切面和模板減小重複代碼。

ioc容器及其使用

他山之石

IOC容器存在價值

Java是一門面向對象編程語言。Java應用本質上是一個個對象及其關係的組合。舉個簡單的例子。面試

在傳統的人員招聘模式中,流程通常都是這樣:HR從多如海的應聘簡歷中挑選而後進行筆試、面試等等一系列篩選後發放offer。這一系列過程複雜並且費時,最關鍵的是結果還不理想,特別是針對某些特定的崗位很難經過這一模式物色到合適的人才資源。 (本身建立特定的對象,使用特定的對象)spring

後來逐漸出現了一些公司專門提供相似的人才尋訪服務,這就是大名鼎鼎的獵頭行業。獵頭的興起能夠說很大程度上改變了人才招聘的模式,如今公司須要招聘某個職位的人才,只須要告訴獵頭我要一個怎樣的人幹怎樣的工做等等要求,獵頭就會經過本身的渠道去物色人才,通過篩選後提供給客戶,大大簡化了招聘過程的繁瑣,提升了招聘的質量和效率。(告訴中間人,中間人自動給你須要、合適的對象)編程

這其中一個很重要的變化就是公司HR將繁瑣的招聘尋訪人才的過程轉移至了第三方,也就是獵頭。相對比而言,IoC在這裏充當了獵頭的角色,開發者即公司HR,而對象的控制權就至關於人才尋訪過程當中的一系列工做編程語言

一句話,在java中,將對象的建立與對象的使用分離開,經過依賴注入(DI)的方式達到對象控制反轉(IOC)的目的。本來須要本身作建立對象、維護各個對象關係,如今統一交給統一專業的人或服務處理。測試

建立對象等操做就是你對對象的控制權,把控制權交給三方,這就是 控制反轉(IOC) 的意思。this

當須要某個對象的時候,三方將合適的對象給你,這個就是 依賴注入(DI) 的意思。spa

IOC具象化

關係

主要類或接口uml圖

IOC容器接口設計圖

ApplicationContext 擴展了BeanFactory後的結果,BeanFactory爲bean對象的出生地。.net

BeanDefinition載入

定義一個bean對象長什麼樣子,在spring中叫BeanDefinition。如何初始化一個BeanDefinition,spring中經常使用三種方式定義:xml文件、註解掃描、java代碼.

加載BeanDefinition

bean的生命週期

spring中bean生命週期.png

Bean的完整生命週期經歷了各類方法調用,這些方法能夠劃分爲如下幾類:

  • Bean自身的方法:這個包括了Bean自己調用的方法和經過配置文件中的init-method和destroy-method指定的方法。
  • Bean級生命週期接口方法:這個包括了BeanNameAware、BeanFactoryAware、InitializingBean和DisposableBean這些接口的方法
  • 容器級生命週期接口方法:這個包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 這兩個接口實現,通常稱它們的實現類爲「後處理器」。
  • 工廠後處理器接口方法:這個包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等很是有用的工廠後處理器  接口的方法。工廠後處理器也是容器級的。在應用上下文裝配配置文件以後當即調用。

舉例(經過註解與java代碼定義bean)

  • 定義一個Animal接口。
  • 定義實現Animal接口的兩個動物Cat,Dog類;
  • 定義一個接口代理AnimalProxy。
  • 定義一個spring Bean java類

實現經過代理類完成不一樣操做。

1.Animal接口

package bean;

public interface Animal {

    public void sayName();
}
複製代碼

2.Cat類

package bean;

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

@Primary
@Component
public class Cat implements Animal {

    public void sayName() {
        System.out.println("this is cat");
    }
}
複製代碼

3.Dog類

package bean;

import org.springframework.stereotype.Component;

@Component
public class Dog implements Animal {
    public void sayName() {
        System.out.println("this is dog");
    }
}
複製代碼

4.AnimalProxy類

package bean;

import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class AnimalProxy implements Animal {

    @Autowired
    private Animal animal;

    public void sayName(){
        animal.sayName();
    }
}
複製代碼

5. AnimalConfig(Bean定義類)

package bean;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

/** * User: Rudy Tan * Date: 2017/11/24 */
@Configuration
@ComponentScan
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AnimalConfig {
}
複製代碼

6.測試類:

import bean.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AnimalConfig.class)
public class AppTest {

    @Autowired
    private AnimalProxy animalProxy;

    @Test
    public void testBeanLoad(){
        animalProxy.sayName();
    }
}
複製代碼

說明:

  • 註解Component:指明該類爲bean類
  • 註解Primary:指明當多個bean對象知足獲取條件時候,該對象優選獲取。
  • 註解Configuration:指明該類爲spring bean定義類。
  • 註解ComponentScan:開啓當前目錄下的bean註解掃描。
  • 註解EnableAspectJAutoProxy:啓用aspectJauto代理。
  • 註解Autowired:該屬性,spring自動載入。

總結,多人我的或多個類協助處理問題或實現某個功能,總得要找個領頭的來管理這些關係吧。

相關文章
相關標籤/搜索