程序的耦合
耦合: 程序間的依賴關係
包括: 類之間的依賴,方法間的依賴
解耦: 降低程序間的依賴關係
實際開發中,應該做到,編譯器不依賴,運行時才依賴
解耦的思想:
-
使用反射來創建對象,而避免使用new關鍵字
-
通過讀取配置文件來獲取要創建的對象的全限定類名
而學習Spring的目的就是爲了將類與類之間的耦合性大大降低。即將對象的創建交給Spring來管理。
spring的管理細節
- 創建bean的三種方式
- bean對象的作用範圍
- bean對象的生命週期
學習內容:
- 創建bean的三種方式
- bean對象的作用範圍
- bean對象的生命週期
- IOC概念和spring中的IOC (Inverse Of Control) 反轉控制 spring中基於XML的IOC環境搭建
- 依賴注入(Dependency Injection)
1. 創建bean的三種方式
- 使用默認的構造函數創建
- 使用普通工廠中的普通方法創建對象(使用某個類中的方法創建對象,並存入spring容器)
- 使用工廠中的靜態方法創建對象(使用某個類中的靜態方法創建對象,並存入spring容器)
注意:第二種和第三種方式都可以用來得到jar包中某個方法返回的對象
示例:
<!--方式一 使用默認的構造函數創建 -->
<bean id="accountService" class="com.xatu.service.impl.AccountServiceImpl"></bean>
<!--方式二 使用普通工廠中的普通方法創建對象(使用某個類中的方法創建對象,並存入spring容器) -->
<bean id="instanceFactory" class="com.xatu.factory.InstanceFactory"></bean>
<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>
<!--方式三 使用工廠中的靜態方法創建對象(使用某個類中的靜態方法創建對象,並存入spring容器)-此例中getAccountService()爲靜態方法->
<bean id="accountService" class="com.xatu.factory.staticFactory" factory-method="getAccountService"></bean>
2.bean對象的作用範圍
bean標籤的scope屬性:
作用: 用於指定的bean的作用範圍
取值:
- singleton 單例的(默認值)
- prototype 多例的
- request 作用於web應用的請求範圍
- session 作用於web應用的會話範圍
- global-session 作用於集羣環境的會話範圍(全局會話範圍),當不是集羣環境時,他就是session
3.bean對象的生命週期
單例對象: 預加載
出生:容器創建時
活着:容器在,則對象存活
死亡:容器不在,對象死亡
總結:單例對象的生命週期和容器的週期相同
多例對象: 懶加載
出生:當我們使用對象時,spring框架爲我們創建
活着:對象只要是在使用過程中就一直活着
死亡:當對象長時間不用,且沒有別的對象使用時,由Java的垃圾回收器回收
4.spring中基於XML的IOC環境的搭建
- 創建一個Maven工程
- 在pom.xml中導入spring依賴
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.2.RELEASE</version>
</dependency>
3.在resources目錄下新建一個bean.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">
</beans>
此時 環境搭建完成。
5.依賴注入
依賴注入即 Dependency Injection
-
IOC的作用:降低程序間的耦合度(依賴關係)
-
依賴關係的管理: 以後都交給spring來維護
在當前類需要用到其他類的對象,由spring爲我們提供,我們只需要在配置文件中說明依賴關係的維護就稱之爲依賴注入
-
依賴注入
能注入的數據有三類:
1.基本類型和String類型
2.基本bean類型(在配置文件中或者註釋配置過的bean)
3.複雜類型/集合類型注入的方式:三種
1.使用構造函數提供
2.使用set方法提供
3.使用註釋提供方式一:構造函數注入
使用的標籤: constructor-arg 標籤出現在bean標籤內
屬性:-
type:用於指定要輸入的數據的數據類型,該數據類型也是構造函數中某個或某些參數的類型
-
index:用於指定要注入的數據給構造函數中指定索引位置的參數賦值,索引位置從0開始
-
name:用於指定給構造函數中指定名稱的參數賦值 (常用)
-
value:用於提供基本類型和String類型的數據
-
ref:用於指定其他的bean類型數據,它指的就是在spring的Ioc核心容器中出現過的bean對象
-
> 如Date類型 可以寫成 <bean id="now" class="java.util.Date"></bean>
> 然後用<constructor-arg>便籤賦值即可
> <constructor-arg name="date" ref="now"></constructor-arg>
優勢: 在獲取bean對象時,注入數據是必須操作,否則對象無法創建成功
弊端: 改變了bean對象的實例化方式,是我們纔開發過程中,如果用不到這些數據,也必須提供
方式二:set方法注入 更常用
**使用的標籤:**property 出現的位置:bean標籤的內部
標籤的屬性:
-
**name:**用於指定注入時所調用的set方法名成 即對應的屬性名
-
**value:**用於提供基本類型和String類型的數據
-
**ref:**用於指定其他的bean類型數據,它指的就是在spring的Ioc核心容器中出現過的bean對象
優勢: 創建對象時沒有明確的限制,可以直接使用某人後遭參數
弊端: 如果由某個成員必須有值,則獲取對象是有可能set方法沒有執行
3.複雜類型的注入
如數字 集合 Properties類型
用於給List結構集合注入的標籤: list array set
用於給Map結構結合注入的標籤: map props
舉例如下:
<bean id="student" class="com.xatu.domain.Student">
<property name="name" value="小王"></property> //簡單類型
<property name="date" ref="now"></property> //基本bean類型
<property name="myArr"> //複雜類型
<array>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</array>
</property>
<property name="myList">
<array>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</array>
</property>
<property name="myset">
<array>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</array>
</property>
<property name="myMap">
<map>
<entry key="test1" value="name1"></entry>
<entry key="test2" value="name2"></entry>
<entry key="test3" value="name3"></entry>
</map>
</property>
<property name="mypros">
<props>
<prop key="test1">name1</prop>
<prop key="test2">name2</prop>
<prop key="test3">name3</prop>
</props>
</property>
</bean>
如下項目:
People.java
//接口 可以解耦
public interface People {
void play(String name,Date date);
}
Student.java
//實現類
public class Student implements People {
private String name;
private Date date;
private List myList;
private String[] myArr;
private Set myset;
private Map<String,String> myMap;
private Properties mypros;
public void setName(String name) {
this.name = name;
}
public void setDate(Date date) {
this.date = date;
}
public String getName() {
return name;
}
public Date getDate() {
return date;
}
public void setMyList(List myList) {
this.myList = myList;
}
public void setMyArr(String[] myArr) {
this.myArr = myArr;
}
public void setMyset(Set myset) {
this.myset = myset;
}
public void setMyMap(Map<String, String> myMap) {
this.myMap = myMap;
}
public void setMypros(Properties mypros) {
this.mypros = mypros;
}
public void play(String name, Date date) {
System.out.println(name + "在" + date + "玩了遊戲" );
}
public void test1(){
System.out.println("Array:" + Arrays.toString(myArr));
System.out.println("set:" + myset);
System.out.println("list:" + myList);
System.out.println("map:" + myMap);
System.out.println("pros:" + mypros);
}
}
testSpring.java
//測試類
public class testSpring {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
Student student = (Student) ac.getBean("student");
student.play(student.getName(),student.getDate());
student.test1();
}
}
bean.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 id="student" class="com.xatu.domain.Student">
<property name="name" value="小王"></property>
<property name="date" ref="now"></property>
<property name="myArr">
<array>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</array>
</property>
<property name="myList">
<array>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</array>
</property>
<property name="myset">
<array>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</array>
</property>
<property name="myMap">
<map>
<entry key="test1" value="name1"></entry>
<entry key="test2" value="name2"></entry>
<entry key="test3" value="name3"></entry>
</map>
</property>
<property name="mypros">
<props>
<prop key="test1">name1</prop>
<prop key="test2">name2</prop>
<prop key="test3">name3</prop>
</props>
</property>
</bean>
<bean id="now" class="java.util.Date"></bean>
</beans>