spring介紹
spring是一個輕量級的開源框架(輕量級-指消耗資源少,開發過程快捷方便)
方便解耦,簡化開發
Spring就是一個大工廠,可以將所有對象創建和依賴的關系維護,交給Spring管理。 --重點了解
AOP編程的支持
Spring提供面向切面編程,可以方便的實現對程序進行權限攔截、運行監控等功能。
聲明式事務的支持
只需要通過配置就可以完成對事務的管理,而無需手動編程。
方便程序的測試
Spring對Junit4支持,可以通過注解方便的測試Spring程序。
方便集成各種優秀框架
Spring不排斥各種優秀的開源框架,其內部提供了對各種優秀框架的直接支持(如:Struts、Hibernate、MyBatis等)。
降低JavaEE API的使用難度
Spring對JavaEE開發中非常難用的一些API(JDBC、JavaMail、遠程調用等),都提供了封裝,使這些API應用難度大大降低。
spring體系
spring大致分為5個模塊:Test、AOP、web數據訪問、集成部分(Data Access/Integration)、核心容器(Core Container)
bean、core、context可以說是spring的三大核心組件這里詳細的介紹下:
spring-core:依賴注入IoC與DI的最基本實現
spring-beans:Bean工廠與bean的裝配
spring-context:spring的context上下文即IoC容器
spring-expression:spring表達式語言
盜一張別人總結的依賴關系圖
所以當我們創建完spring項目后,pom.xml文件中自動添加了spring-context后,這樣依賴的core、beans等jar包就全部導入了
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.framework.version}</version> </dependency>
后續補充底層的實現原理
Spring最大的特性應該就是控制反轉和依賴注入了
看了不下十幾個對於這兩個名詞的解釋,這里用自己的話概括下
控制反轉:就是把創建對象的權利從自己交給外部的容器,不再由自己創建,控制權發生了改變
依賴注入:當運行一個A類需要依賴另一個B類的對象時,不需要自己new對象,而是通過容器控制程序創建對象B並注入到A里面
下面用xml配置的方式鞏固對這兩種設計的理解
基於xml配置Bean
這里先介紹下標簽的基本含義
bean-定義一個Bean實例的信息 通俗的講就是一個對象
bean屬性:
id 指定生成的Bean實例名稱
name 指定生成的Bean實例名稱
scope 設定Bean實例的生成方式 默認是singleton模式 還有prototype多例模式 request、session、global session模式
init-method 初始化時調用的方法 比如對象中含有a方法,可以配置此屬性這樣每次生成對象時都會調用a方法
destroy-method 屬性實例銷毀時要調用的方法 同init-method 但是需要scope設置成singleton模式
bean子標簽
property 官方的話術是用來配置Bean實例的依賴關系(set方式注入,屬性一定要有set方法),通俗講就是配置對象屬性的值
constructor-arg 用來配置Bean實例的依賴關系(構造方式注入)
ref constructor-arg、property、list、set、entry等標記的子標記,指定一個Bean實例
value constructor-arg、property、list、set、entry等標記的子標記,指定一個常量
list 用以封裝List或數組類型屬性的依賴注入 具體的元素通過ref或value子標記指定
set 封裝Set類型屬性的依賴注入 具體的元素通過ref或value子標記指定
map 封裝Map類型屬性的依賴注入 應為map是鍵值對,需要用entry子標簽設置“鍵/值”對
了解了標簽基本的含義,現在實際操作下,先新建一個spring工程、在ioc的包下創建測試類User、Car;在resources下創建Spring Bean Configuration file模板的ioctest.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>
package ioc; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; public class Car { private String name; private double price; public Car() { } public Car(String name, double price) { super(); this.name = name; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } @Override public String toString() { return "Car [name=" + name + ", price=" + price + "]"; }
}
User類,寫的挺多,大部分都是set、get方法
package ioc; import java.util.List; import java.util.Map; import java.util.Set; public class User { private String name; private int age; private String sex; private Car car; private List<Integer> intlist; private List<Car> carList; private Set<Car> carSet; private Map<Integer, Car> carMap; //默認構造方法 public User() { } // 有參構造方法 public User(String name, Car car, List<Car> carList) { super(); this.name = name; this.car = car; this.carList = carList; } public List<Integer> getIntlist() { return intlist; } public void setIntlist(List<Integer> intlist) { this.intlist = intlist; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } public List<Car> getCarList() { return carList; } public void setCarList(List<Car> carList) { this.carList = carList; } public Set<Car> getCarSet() { return carSet; } public void setCarSet(Set<Car> carSet) { this.carSet = carSet; } public Map<Integer, Car> getCarMap() { return carMap; } public void setCarMap(Map<Integer, Car> carMap) { this.carMap = carMap; } @Override public String toString() { return "User [name=" + name + ", age=" + age + ", sex=" + sex + ", car=" + car + ", carList=" + carList + ", carSet=" + carSet + ", carMap=" + carMap + "]"; }; public void init() { System.out.println("開始調用"); } public void destroy() { System.out.println("結束調用"); } }
<?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"> <!-- 創建一個對象user 對象名稱就是user 類名用class內容表示 要加上包名 --> <!-- scope設置成prototype表示每次調用都會生成一個新的對象 可以打印hashcode查看 --> <bean name="user" class="ioc.User" scope="prototype" init-method="init" destroy-method="destroy"> <!-- 構造函數參數的配置 --> <constructor-arg name="name" value="張三"></constructor-arg> <!-- 基本類型用value 引用類型用ref表示 --> <constructor-arg name="car" ref="car1"></constructor-arg> <constructor-arg name="carList"> <list> <!-- 可以在list中直接創建一個對象,但是外部無法使用 --> <bean id="car2" class="ioc.Car"> <property name="name" value="奔馳"></property> <property name="price" value="1000000"></property> </bean> </list> </constructor-arg> <property name="age" value="18"></property> </bean> <bean name="user2" class="ioc.User" init-method="init" destroy-method="destroy"> <!-- 通過屬性的set方法給對象賦值 --> <property name="age" value="28"></property> <property name="name" value="王老五"></property> <property name="carSet"> <set> <ref bean="car1" /> <ref bean="car3" /> </set> </property> <!-- 給map類型的實例賦值 --> <property name="carMap"> <map> <entry key="1"> <ref bean="car1"></ref> </entry> <entry key="2"> <ref bean="car1"></ref> </entry> </map> </property> </bean> <bean id="car1" class="ioc.Car"> <property name="name" value="寶馬"></property> <property name="price" value="500000"></property> </bean> <bean id="car3" class="ioc.Car"> <property name="name" value="特斯拉"></property> <property name="price" value="700000"></property> </bean> </beans>
重新配置xml文件后,寫test類驗證
package ioc; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestMain { public static void main(String[] args) { //獲取容器對象 ApplicationContext ac=new ClassPathXmlApplicationContext("ioctest.xml"); //通過容器獲取配置的javabean User user=(User)ac.getBean("user"); System.out.println(user); User user2=(User)ac.getBean("user2"); System.out.println(user2); } }