什麼是Spring
Spring是一個容器,管理着整個應用程式中所有的bean的生命周期和依賴關系,進而降低耦合度,具體分為下面兩種情況。
spring的出現就是為了解耦合,充當一個管家的角色。
Spring把代碼根據功能劃分:
- 主業務邏輯代碼
- 代碼邏輯聯系緊密,耦合度高,複用性低。
- 降低主業務代碼之間的耦合度 =>> 控制反轉 IOC
- 系統級業務邏輯(交叉業務邏輯)
- 功能相對獨立,沒有具體的業務場景,主要是提供系統級服務,如日志,安全,事務等,複用性很強。
- 降低主業務邏輯和系統級服務之間的耦合度 =>> 面向切面程式設計 AOP
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuEzMidDOwkzMhRzYmlDNyQWY0QWZyQDZmJTNwcjNiJ2MfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.png)
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()
}
結果
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()
}