08.SSM框架集~Spring(一)IOC/DI
本文是上一篇文章的後續,詳情點擊該鏈接
本章資料 提取碼:cpss
關於Spring,我們在第一篇文章的時候,就已經有了介紹,可以回顧一下。 文章鏈接
Spring
環境搭建:
關於版本. 在spring3之前, spring只提供一個jar, spring.jar; 從spring3之後, 官方對spring做了拆分, 分成了多個jar包(spring-aop, spring-beans, spring-context, spring-expression, spring-core, spring-jdbc, spring-tx, spring-web, spring-webmvc, ...).
Jar包和源碼的下載地址(文章最上方也有本人下載好的)
https://github.com/spring-projects/spring-framework/tags
https://repo.spring.io/libs-release-local/org/springframework/spring/
介紹Spring Framework Runtime
Test:
spring-test.jar. Spring提供的測試工具, 可以整合JUnit測試, 簡化測試環節.
Core Container
Spring的核心組件, 包含了Spring框架最基本的支撐
Beans, 對應spring-beans.jar. Spring進行對象管理時依賴的jar包
Core, 對應spring-core.jar, Spring核心jar包
Context, 對應spring-context.jar, Spring容器上下文對象
SpEL, 對應spring-expression.jar, Spring表達式語言
AOP
面向切面編程, 對應spring-aop.jar
Data Access
Spring對數據訪問層的封裝
JDBC, 對應spring-jdbc.jar. Spring對jdbc的封裝, 當需要使用spring連接數據庫時使用. spring-jdbc.jar需要依賴spring-tx.jar
Transactions, 對應spring-tx.jar. 事務管理
ORM, 對應spring-orm.jar. spring整合第三方orm框架需要使用的jar包, 例如Hibernate框架
Web
Spring對javax下的接口或類做的擴展功能
spring-web.jar, 對Servlet, filter, Listener等做的增強
spring-webmvc.jar, 實際上就是SpringMVC框架. 需要依賴spring環境和spring-web.jar
Spring中的IOC
IOC的使用:
我們使用MVC進行開發的時候,數據在各層之間進行傳遞,數據在業務上構成一個鏈條,這個鏈條稱之爲責任鏈
基於責任鏈開發模式,我們發現代碼層和層之間相互調用,造成了層和層的耦合性太高,並且後期的擴展性太低,我們寫代碼的時候講究的原則———低耦合,高內聚。
解決方案:
Spring IOC,
基本使用流程:
創建Maven的war項目然後配置web的相關依賴以及項目結構的配置
配置pom.xml
<?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.alvin</groupId>
<artifactId>SpringCreate</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!-- IOC依賴座標 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!-- 日誌座標 -->
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
如果倉庫裏面沒有你要導入的jar包,那麼點擊import就會自動下載
在pom.xml文件中配置SpringIOC的依賴
使用Spring運行第一個程序
創建Service和Controller,以及配置文件applicationContext.xml
Service接口和實現類
public interface AdminService {
//查詢用戶信息
void FindAll();
}
public class AdminServiceImpl implements AdminService {
private String name;
public AdminServiceImpl(String name){
this.name = name;
}
public AdminServiceImpl(){
System.out.println("構造方法已實現~");
}
public void FindAll() {
System.out.println("查詢結果: " + name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "AdminServiceImpl{" +
"name='" + name + '\'' +
'}';
}
}
配置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">
<!-- 創建業務層對象 -->
<beans>
<bean id="adminService" class="com.alvin.service.impl.AdminServiceImpl"></bean>
</beans>
</beans>
Controller調用
public class AdminServlet {
public static void main(String[] args) {
//解析applicationContext.xml文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//獲得已經創建好的對象
AdminService adminService = applicationContext.getBean("adminService",AdminService.class);
//調用
adminService.FindAll();
}
}
Spring IOC創建對象的三種方式
構造器方式
有參構造
無參構造
剛剛上述方法用的則是無參構造,我們現在就來試試有參構造吧!
有參構造方法
applicationContext:
<!--有參數的構造器
特點:Spring容器對根據配置調用的有參構造器創建一個帶有初始化數據的對象
使用:constructor-arg:使用bean的字標籤來聲明調用的構造器的形參的個數
一個字標籤表示一個參數
屬性:index:參數的下標
type:參數的類型,全限定路徑
name:參數的形參名
value:參數要給的值-->
<beans>
<bean id="adminService2" class="com.alvin.service.impl.AdminServiceImpl">
<constructor-arg index="0" type="java.lang.String" name="name" value="小明"/>
</bean>
</beans>
工廠模式
pom.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 class="com.alvin.factroy.Factory" id="factory" factory-method="getInstance">
<constructor-arg name="param" value="stu"></constructor-arg>
</bean>
</beans>
public class Test2 {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContextFactory.xml");
Factory student = applicationContext.getBean("factory",Factory.class);
}
}
class Factory {
public People getInstance(String param){
if("student".equals(param)){
return new Student();
}else if("teacher".equals(param)){
return new Teacher();
}
return null;
}
}
interface People {
void Run();
}
class Teacher implements People{
@Override
public void Run() {
System.out.println("老師跑");
}
}
class Student implements People{
@Override
public void Run() {
System.out.println("學生跑");
}
}
Spring中的DI
作用:給創建好的對象中的全局的屬性或者對象進行賦值操作
英文全稱(Dependency Injection)
中文名稱:依賴注入
依賴:一個類在另一個類中作爲全局屬性時
注入:通過外部給自己屬性(或其他內容)進行賦值
類與類之間的關係:
繼承(官方名稱:泛化)
實現
依賴:類和類之間的關係是偶然的,臨時的.在代碼層面另一個類當作這個類的方法參數或局部變量
關聯:類與類之間存在一定聯繫,可以是單向聯繫可以是雙向聯繫.例如:學生和老師. (平時理解關聯是一種強依賴),體現在代碼層面,另一個類是這個類的全局屬性.
聚合:類與類之間是可以單獨存在的.但是有存在整體和部分的關係.例如:機箱和CPU.體現在代碼層面:另一個類是這個類的全局屬性.
組合:類與類之間是整體和部分之間的部分,不可分.例如人和心臟.體現在代碼層面:另一個類是這個類的全局屬性.
關係強度:組合 > 聚合 > 關聯 > 依賴
DI的意義:
解除類與類之間高耦合性.
爲什麼稱DI和IOC是同一個事情.
Spring幫助創建對象的過程叫做IOC,創建對象時給對象中全局對象賦值叫做DI,所以認爲IOC和DI是同一個事情.
DI注入的方式:
使用set方法
使用有參構造器
自動注入
使用有參構造器
創建班級類和學生類
public class Student {
private String name;
private String sex;
private int age;
private Clazz clazz;
}
public class Clazz {
private int clazzno;
private String cname;
}
//自行添加get,set
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="cla" class="spring.alvin.student.Clazz">
<constructor-arg name="cname" value="javaSE"></constructor-arg>
<constructor-arg name="clazzno" value="507"></constructor-arg>
</bean>
<bean id="stu" class="spring.alvin.student.Student">
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="name" value="張三"></constructor-arg>
<constructor-arg name="sex" value="男"></constructor-arg>
<!-- 將上面創建好的cla引入到下面 -->
<constructor-arg name="clazz" ref="cla"></constructor-arg>
</bean>
</beans>
Test操作
public class Test {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = applicationContext.getBean("stu",Student.class);
System.out.println(student);
}
}
使用set方法
<bean id="stu" class="spring.alvin.student.Student">
<property name="name" value="李四"></property>
<property name="sex" value="男"></property>
<property name="age" value="20"></property>
<property name="clazz" ref="cla"></property>
</bean>
看起來好像差不多,實際上前者是用構造器,後者是用set
value和ref的使用場景:
value: 如果注入的屬性類型是基本數據類型(包含String)使用value
ref: 如果注入的屬性類型是對象,這個時候使用ref
使用自動注入:
底層走的是Set方法;
byName: 這個時候就會在當前的XML中尋找bean的id名稱和需要注入的屬性名一致進行匹配。
案例:
<!-- 有參構造方式進行注入 -->
<bean id="clazz" class="spring.alvin.student.Clazz">
<constructor-arg name="cname" value="javaSE"></constructor-arg>
<constructor-arg name="clazzno" value="507"></constructor-arg>
</bean>
<bean id="stu" class="spring.alvin.student.Student" autowire="byName"></bean>
此時id = clazz是存在的對象,所以可以找到。如果不存在,就無法找到
byType: 這個時候就會在當前xml中尋找[bean標籤的類型]和需要注入實體中的[屬性名]一致,進行匹配注入
<bean id="stu" class="spring.alvin.student.Student" autowire="byType"></bean>
constructor: 這個時候首先會根據名稱進行查找,如果名稱沒有一致再根據類型進行查找。 {底層走的是構造器}
<bean id="stu" class="spring.alvin.student.Student" autowire="constructor"></bean>
注意: 必須要有有參構造器才能執行!
DI其他類型值的注入:
數組,List,Set,Map
User類
public class User {
private String[]arr;
private List<String> li;
private Set<String> set;
private Map<String,String>map;
}
//get set自行添加
給數組,List,Set,Map添加
<bean id="us" class="spring.alvin.student.User">
<!-- 數組 -->
<property name="arr">
<array>
<value>A</value>
<value>B</value>
<value>C</value>
</array>
</property>
<!-- list -->
<property name="li">
<list>
<value>D</value>
<value>E</value>
<value>F</value>
</list>
</property>
<!-- Set -->
<property name="set">
<set>
<value>G</value>
<value>H</value>
<value>I</value>
</set>
</property>
<!-- Map -->
<property name="map">
<map>
<entry>
<key><value>1</value></key>
<value>小明</value>
</entry>
<entry>
<key><value>2</value></key>
<value>小海</value>
</entry>
</map>
</property>
</bean>