Spring框架:DI依賴注入思想和IOC控制反轉、配置文件詳解、典型案例分析、容器架構、API

Spring


Spring介紹

  • 官網

  • 百科

    Spring框架是由於軟件開發的複雜性而創建的。Spring使用的是基本的JavaBean來完成以前只可能由EJB完成的事情。然而,Spring的用途不僅僅限於服務器端的開發。從簡單性、可測試性和鬆耦合性角度而言,絕大部分Java應用都可以從Spring中受益。

  • GitHub/Gitee

Spring優點

  • DI(Dependency Injection)與IOC(Inverse Of Control)
  • AOP(Aspect Oriented Programming)
  • 與所有框架完美集成
  • 使得JDBC/事務等更加方便

Spring容器和IOC與DI思想

在這裏插入圖片描述

Spring容器爲我們管理對象的創建和銷燬全過程

對於像jdbc或是連接池需要經歷一系列的對象創建、使用和銷燬過程的項目,在需求越來越大,對應的對象越來越多,整個過程如果通過我們自己去處理將會十分複雜.

Spring容器通過依賴注入,和自動裝配(過程)實現控制反轉(結果)

類與類之間的依賴關係若通過new構造方法創建對象的方式解決,耦合性太強.Spring獲得創建對象的控制權,程序需要什麼對象,只要去容器中取

  • DI(Dependency Injection)依賴注入就是不通過原始的方法創建對象實例,而是通過自動裝配(底層通過反射實現)依賴容器爲程序注入對象,自動裝配通過配置文件,反射來獲取程序需要的對象類型、實例名
  • IOC(Inverse Of Control)控制反轉:將實例化對象的控制權交給Spring容器

Spring配置


IOCjar包介紹

jar包 概述
Spring-core Spring的核心工具包,spring的其它包都要用到該jar中的包
Spring-beans 包含配置文件,bean的創建等,所有jar包都需要用到
Spring-context 在上面兩個jar完成基礎IOC功能上提供擴展服務,此外還提供許多企業級服務的支持,有郵件服務、任務調度、JNDI定位,EJB集成、遠程訪問、緩存以及多種視圖層框架的支持。
Spring-expression Spring表達式語言,spel表達式,SpEL支持標準數學運算符,關係運算符,邏輯運算符,條件運算符,集合和正則表達式等。
Spring-context-support Spring context的擴展支持,用於MVC方面,比如支持freemarker等模板引擎

Maven引入jar包

<properties>
    <spring.version>5.1.5.RELEASE</spring.version>
</properties>
<dependencies>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-expression</artifactId>
        <version>${spring.version}</version>
    </dependency>
</dependencies>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.6.0</version>
    <configuration>
        <source>1.8</source> <!-- 源代碼使用jdk1.8支持的特性 -->
        <target>1.8</target> <!-- 使用jvm1.8編譯目標代碼 -->
               <compilerArgs> <!-- 傳遞參數 -->
                    <arg>-parameters</arg>
                    <arg>-Xlint:unchecked</arg>
                    <arg>-Xlint:deprecation </arg>
              </compilerArgs>
    </configuration>
</plugin>
日誌配置
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.26</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.26</version>
</dependency>

在resources文件夾中加入log4j.properties

log4j.rootCategory=DEBUG, stdout 

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n

IOC配置文件

在resources文件夾中加入applicationContext.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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

  </beans>

Spring案例剖析


配置文件加入
  1. 創建Maven普通項目,添加jar包以及配置文件.

  2. 創建StudentService類,在applicationCotext中配置類信息

    <bean id="studentService" class="com.edu.bean.StudentService"></bean>
    
  3. 創建測試,在鼠標點擊類名按下Alt+Enter選擇Create Test,最後在測試方法註解中去掉org.junit.並導入junit包

    @Test
        public void show() {
            //1、加載容器,通過配置文件加載ApplicationContext,beanFactory(原始)(SpringIOC容器)
            //classpath:會在當前項目resources下面去找(編譯後target下面找)
            //classpath*:查找除了在本項目包括其他項目的jar包的resources文件夾路徑
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath*:applicationContext.xml");
            //2、創建對象
            StudentService studentService = (StudentService) context.getBean("studentService");
            //3、調用對象方法
            studentService.show();
            //4、銷燬
            //classPathXmlApplicationContext.close();
            context.registerShutdownHook();//更爲優雅
        }
    

bean標籤屬性詳解

id/name

對象的唯一標識,兩者性質一樣,value也不能相同

Scope

設置對象的實例類型

概述
singleton SpringIoc容器只會創建該Bean的唯一實例,所有的請求和引用都只使用這個實例
prototype 每次請求都創建一個實例
request 在一次Http請求中,容器會返回該Bean的同一個實例,而對於不同的用戶請求,會返回不同的實例。需要注意的是,該作用域僅在基於Web的Spring ApplicationContext情形下有效,以下的session和global Session也是如此
session 同上,唯一的區別是請求的作用域變爲了session
global session 全局的HttpSession
autowire:自動裝配

爲依賴的javabean設置自動裝配的方式,在原對象中必須創建getter,setter(javabean規範),框架底層調用實現

概述
no 即不啓用自動裝配。autowire默認的值。
byName 通過屬性的名字的方式查找JavaBean依賴的對象併爲其注入,使用Seter方法爲其注入。
byType 通過屬性的類型查找JavaBean依賴的對象併爲其注入。使用Seter方法爲其注入
constructor byType一樣,也是通過類型查找依賴對象。與byType的區別在於它不是使用Seter方法注入,而是使用構造子注入
autodetect 在byType和constructor之間自動的選擇注入方式
default 由上級標籤的default-autowire屬性確定

注意:在配置bean時,標籤中autowire屬性的優先級比其上級標籤高,即是說,如果在上級標籤中定義default-autowire屬性爲byName,而在中定義爲byType時,Spring IoC容器會優先使用標籤的配置。

factory-bean/factory-method 工廠方法注入
<bean factory-bean="" factory-method=""></bean>
lazy-init:延遲加載

值爲true時,在Spring容器初始化時該javabean不加載而是等到程序使用該類時加載

默認值爲false,javabean會隨着Spring容器一同被加載.

注意:

  • lazy-init只有在scope爲singleton(單例)時才生效
  • 若lazy-init的javabean被不是lazy-init依賴,則前者被後者第一次主動使用,兩者同時加載
init-method/destroy-method

初始化(構造方法先執行)和銷燬前javabean時調用的方法

關於在spring 容器初始化 bean 和銷燬前所做的操作定義方式有三種:

第一種:通過@PostConstruct 和 @PreDestroy 方法 實現初始化和銷燬bean之前進行的操作

第二種是:通過 在xml中定義init-method 和 destory-method方法

第三種是: 通過bean實現InitializingBean和 DisposableBean接口

Spring容器架構


ApplicationContext

在這裏插入圖片描述

類名 概述
AnnotationConfigApplicationContext 基於註解開發時使用的容器
ClassPathXmlApplicationContext 查找配置文件時默認到classpath路徑下去找,也就是編譯後的classes文件夾
FileSystemXmlApplicationContext 查找配置文件默認到當前項目的文件系統路徑
AnnotationConfigApplicationContext案例分析
//@Configuration標記的方法將該類描述爲配置類,就類似一個xml配置文件,其中多個@Bean標記的方法將被AnnotationConfig(Web)ApplicationContext對象掃描,並用於構造javabean,初始化Spring容器
@Configuration
public class MyConfig {
    //@Bean註解標記的方法返回的bean將被交與容器管理並在容器中以name的value值作爲標識
    @Bean(name = "studentService")
   public StudentService getstudentService()
    {
        return new StudentService();
    }
}
public class AnnoConfigTest {
    @Test
    public void show()
    {
        //1、通過註解構造的配置類獲取容器
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        //2、獲取對象實例
        StudentService service = context.getBean(StudentService.class);
        service.start();
        //3、銷燬
        context.registerShutdownHook();
    }
}

BeanFactory和ApplicationContext的區別

BeanFactory

是Spring裏面最低層的接口,提供了最簡單的容器的功能,只提供了實例化對象和拿對象的功能;

ApplicationContext

應用上下文,繼承BeanFactory接口,它是Spring的一各更高級的容器,提供了更多的有用的功能;

  1. 國際化(MessageSource)

  2. 訪問資源,如URL和文件(ResourceLoader)

  3. 載入多個(有繼承關係)上下文 ,使得每一個上下文都專注於一個特定的層次,比如應用的web層

  4. 消息發送、響應機制(ApplicationEventPublisher)

  5. AOP(攔截器)

兩者裝載bean的區別

BeanFactory

BeanFactory在啓動的時候不會去實例化Bean,中有從容器中拿Bean的時候纔會去實例化;

ApplicationContext

ApplicationContext在啓動的時候就把所有的Bean全部實例化了。它還可以爲Bean配置lazy-init=true來讓Bean延遲實例化;

選擇

延遲實例化的優點:(BeanFactory

應用啓動的時候佔用資源很少;對資源要求較高的應用,比較有優勢;

不延遲實例化的優點: (ApplicationContext

  1. 所有的Bean在啓動的時候都加載,系統運行的速度快;
  2. 在啓動的時候所有的Bean都加載了,我們就能在系統啓動的時候,儘早的發現系統中的配置問題
  3. 建議web應用,在啓動的時候就把所有的Bean都加載了。(把費時的操作放到系統啓動中完成)

SpringAPI


spring的getBean方法

在這裏插入圖片描述

依賴注入(兩種)

setter注入
<bean class="com.edu.bean.Student">
<!--        int-->
        <property name="age" value="23" ></property>
<!--        String-->
        <property name="name" value="DLz"></property>
<!--        Array-->
        <property name="friends">
            <array>
                <value>zyh</value>
                <value>rit</value>
                <value>laz</value>
            </array>
        </property>
<!--        List-->
        <property name="girlfriends">
            <list>
                <value>zjey</value>
            </list>
        </property>
<!--        Set<Object>-->
        <property name="courses">
            <set>
                <bean class="com.edu.bean.Course">
                    <property name="id" value="1"/>
                    <property name="name" value="語文"/>
                </bean>
                <bean class="com.edu.bean.Course">
                    <property name="id" value="2"/>
                    <property name="name" value="數學"/>
                </bean>
            </set>
        </property>
<!--        Properties-->
        <property name="score">
            <props>
                <prop key="1">88</prop>
                <prop key="2">100</prop>
            </props>
        </property>
    </bean>
構造注入
<bean class="com.edu.bean.Student">
        <constructor-arg index="0" value="Dlz"/>
        <constructor-arg index="1" value="23"/>
        <constructor-arg index="2">
            <list>
                <value>sjw</value>
                <value>jyx</value>
            </list>
        </constructor-arg>
        <constructor-arg index="3">
            <list>
                <value>zzyy</value>
            </list>
        </constructor-arg>
        <constructor-arg index="4">
            <set>
                <bean class="com.edu.bean.Course">
                    <property name="id" value="1"/>
                    <property name="name" value="語文"/>
                </bean>
                <bean class="com.edu.bean.Course">
                    <property name="id" value="2"/>
                    <property name="name" value="數學"/>
                </bean>
            </set>
        </constructor-arg>
        <constructor-arg index="5">
            <props>
                <prop key="1">88</prop>
                <prop key="2">100</prop>
            </props>
        </constructor-arg>
    </bean>

待更新…

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