天天看點

Spring概述

什麼是Spring

Spring是一個容器,管理着整個應用程式中所有的bean的生命周期和依賴關系,進而降低耦合度,具體分為下面兩種情況。

spring的出現就是為了解耦合,充當一個管家的角色。

Spring把代碼根據功能劃分:

  1. 主業務邏輯代碼
    1. 代碼邏輯聯系緊密,耦合度高,複用性低。
    2. 降低主業務代碼之間的耦合度 =>> 控制反轉 IOC
  2. 系統級業務邏輯(交叉業務邏輯)
    1. 功能相對獨立,沒有具體的業務場景,主要是提供系統級服務,如日志,安全,事務等,複用性很強。
    2. 降低主業務邏輯和系統級服務之間的耦合度 =>> 面向切面程式設計 AOP
Spring概述

Spring體系結構

一,控制反轉 IOC Inversion of Control

是一種思想,一個概念

IOC實作的兩種方式

1. 依賴注入 DI Dependency Injection

2. 依賴查找 DL Dependency Lookup

建立第一個Spring項目

建立Maven工程

POM檔案

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bjxl</groupId>
    <artifactId>spring4</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <kotlin.version>1.1.51</kotlin.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>4.2.6.RELEASE</version>
        </dependency>
        <!--單元測試-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--日志-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!--相當于slf4j-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib-jre8</artifactId>
            <version>${kotlin.version}</version>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-test</artifactId>
            <version>${kotlin.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <version>${kotlin.version}</version>
                <executions>
                    <execution>
                        <id>compile</id>
                        <phase>compile</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <configuration>
                            <sourceDirs>
                                <source>src/main/java</source>
                                <source>src/main/interface</source>
                            </sourceDirs>
                        </configuration>
                    </execution>
                    <execution>
                        <id>test-compile</id>
                        <phase>test-compile</phase>
                        <goals>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <jvmTarget>1.8</jvmTarget>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
           

ServiceImpl

package impl

import face.ISomeService

/**
 * Created by futao on 2017/9/29.
 */
class ISomeServiceImpl : ISomeService {
    override fun doFirst(): String {
        println("執行doFirst()方法")
        return "abcde"
    }

    override fun doSecond() {
        println("執行doSecond()方法")
    }

}
           

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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--bean容器-->
    <!--對象容器-->
    <!--注冊Service對象,等于Java代碼中 ISomeServiceImpl iss = new ISomeServiceImpl()
        這個對象是在Spring容器被初始化的時候Spring自動建立的
    -->
    <bean id="iss" class="impl.ISomeServiceImpl"/>
</beans>
           

測試

package ServiceTest

import impl.ISomeServiceImpl
import org.junit.Test
import org.springframework.context.ApplicationContext
import org.springframework.context.support.ClassPathXmlApplicationContext

/**
 * Created by futao on 2017/9/29.
 */
class myTest {
    /**
     * 傳統方式 new對象
     */
    @Test
    fun test() {
        val iSomeServiceImpl = ISomeServiceImpl()
        iSomeServiceImpl.doFirst()
        iSomeServiceImpl.doSecond()
    }

     /**
     * 從bean容器裡面擷取
     */
    @Test
    fun test02() {
        //加載Spring配置檔案,建立Spring對象,這個時候對象就已經全部被加載到Spring容器當中了
//        val container = ClassPathXmlApplicationContext("applicationContext.xml")
        val container = FileSystemXmlApplicationContext("D:\\eclipse-workspace\\spring4\\src\\main\\resources\\applicationContext.xml")
        //從容器中擷取指定Bean對象
        val iss = container.getBean("iss") as ISomeServiceImpl
        iss.doSecond()
        iss.doFirst()
    }
}
}
           

bean的裝配

動态工廠bean

package Factory

import impl.ISomeServiceImpl

/**
 * Created by futao on 2017/9/29.
 */
class dynamicFactory {
    fun getSomeService(): ISomeServiceImpl {
        return ISomeServiceImpl()
    }
}
           
<?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.xsd">

    <!--bean容器-->
    <!--對象容器-->
    <!--注冊Service對象,等于Java代碼中 ISomeServiceImpl iss = new ISomeServiceImpl()
        這個對象是在Spring容器被初始化的時候Spring自動建立的
    -->
    <!--<bean id="iss" class="impl.ISomeServiceImpl"/>-->
    <bean id="issFactory" class="Factory.dynamicFactory"/>
    <bean id="iss" factory-bean="issFactory" factory-method="getSomeService"/>
</beans>
           

靜态工廠bean

....

容器中Bean的作用域

scope="prototype" 原型模式,每次都會建立一個新的對象(真正使用的時候才會被建立,每擷取一次,都會建立一個新的不同的對象)

scope="singleton" 單例模式,對象隻會被建立一次(容器初始化的時候就會進行建立,也就是xml檔案加載的時候)(預設的)

Bean後處理器

實作BeanPostProcessor 接口

重寫方法postProcessAfterInitialization()和postProcessAfterInitialization()

package beanHandler

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

/**
 * Created by futao on 2017/9/29.
 */
class myBeanPostPrecess : BeanPostProcessor {
    //p0 目前調用執行'Bean後處理器'的Bean對象
    //p1 目前調用執行'Bean後處理器'的bean對象的id
    override fun postProcessBeforeInitialization(p0: Any?, p1: String?): Any {
        println("執行了${p0!!::class.java.simpleName},$p1,Before")
        return p0
    }

    override fun postProcessAfterInitialization(p0: Any?, p1: String?): Any {
        println("執行了${p0!!::class.java.simpleName},$p1,After")
        return p0
    }
}
           
@Test
    fun test03() {
        val iss = ClassPathXmlApplicationContext("applicationContext.xml")
        val service = iss.getBean("iss") as ISomeServiceImpl
        service.doFirst()
        service.doSecond()


        println("================")

        val s2=iss.getBean("dyb") as ISomeServiceImpl
        s2.doSecond()
        s2.doFirst()
    }
           

結果

Spring概述

Result

Bean的生命周期

package impl

import face.ISomeService

/**
 * Created by futao on 2017/9/29.
 */
class ISomeServiceImpl : ISomeService {
    override fun doFirst(): String {
        println("執行doFirst()方法")
        return "abcde"
    }

    override fun doSecond() {
        println("執行doSecond()方法")
    }

    fun initAtfer() {
        println("初始化之後")
    }

    fun beforeDestory() {
        println("銷毀之前")
    }

}
           

XML

<bean id="iss" class="impl.ISomeServiceImpl" init-method="initAtfer" destroy-method="beforeDestory"/>
           

Test

@Test
    fun test03() {
    
        val iss = ClassPathXmlApplicationContext("applicationContext.xml")
        val service = iss.getBean("iss") as ISomeServiceImpl
        println(service.doFirst())
        service.doSecond()
        println("================")
        val s2=iss.getBean("dyb") as ISomeServiceImpl
        s2.doSecond()
        s2.doFirst()
    //銷毀方法的執行需要兩個要求
        /*
        *   1)被銷毀的對象需要是singleton的
        *   2)容器要顯式地關閉
        * */
        iss.destroy()
    }