Spring_day01
第一章、Spring框架的介紹
1. 自定義Bean工廠解耦
知識補充:
JDK的類:
java.util.ResourceBundle:專門用來讀取bean.properties
方法:
(1) ResourceBundle類靜態方法 getBundle(組態檔名)回傳本類物件
(2) ResourceBundle物件的方法getString(組態檔的鍵)回傳值
方法測驗demo
public static void main(String[] args) { //讀取bean.properties //JDK的類,java.util.ResourceBundle 專門對付bean.properties //ResourceBundle類靜態方法 getBundle(組態檔名)回傳本類物件 ResourceBundle bundle = ResourceBundle.getBundle("bean"); //bundle物件的方法getString(組態檔的鍵)回傳值 String userService = bundle.getString("UserService"); System.out.println("userService = " + userService); }
(1)dao層
public interface UserDao {
} public class UserDaoImpl implements UserDao {
}
(2)service層
public interface UserService {
} public class UserServiceImpl implements UserService { }
(3)bean工廠類
/* BeanFactory:讀取組態檔,創建物件 * */ public class BeanFactory implements Serializable { /* 定義靜態方法,傳遞介面型別,傳遞介面的class物件 回傳個介面的實作類物件 Class<T> clazz 傳遞介面的Class物件,泛型T就是介面型別 * */ public static <T> T getInstance(Class<T> clazz){ T obj = null; try { ResourceBundle bundle = ResourceBundle.getBundle("bean"); //傳遞鍵獲取值,一個類的全路徑名 //Class類的方法,getSimpleName,獲取class物件的類的簡稱 String string = bundle.getString(clazz.getSimpleName()); //反射創建物件 Class cla = Class.forName(string); obj = (T)cla.newInstance(); } catch (Exception e) { e.printStackTrace(); } return obj; } }
(4)bean.properties檔案
UserService=com.atguigu.service.impl.UserServiceImpl
UserDao=com.atguigu.dao.impl.UserDaoImpl
(5)測驗類
public class MainTest { @Test public void testMyIOC() { //呼叫BeanFactory的靜態方法getInstance(介面名) 回傳實作類物件 UserService userService = BeanFactory.getInstance(UserService.class); System.out.println("userService = " + userService); UserDao instance = BeanFactory.getInstance(UserDao.class); System.out.println("instance = " + instance); } }
第二章、SpringIOC
1. IOC容器的概念和作用
(1)概念:inverse of control (反轉控制/控制反轉),我們之前在一個java類中通過new的方式去引入外部資源(其他類等),這叫正向;現在Spring框架幫我們去new,你什么時候需要你去問Spring框架要,這就是反轉(創建物件權利的一個反轉)
(2)作用:IOC解決程式耦合問題
2. IOC容器的使用
(1)匯入Spring框架依賴的jar包
<!-- 添加spring框架的jar context:背景關系,框架核心包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.6.RELEASE</version> </dependency>
(2)定義類
package com.atguigu.ioc; /* HappyComponent 類的物件,放在Spring框架的IOC容器中存盤 IOC:控制反轉() * */ public class HappyComponent {public void doWork() { System.out.println("component do work ..."); } }
(3)放進IOC容器中
標簽名字:<bean>
屬性: id :這個物件的唯一標識
class:配置的類的全類名
scope:物件的作用域,spring框架的物件容器中物件的作用域是兩個單例模式(默認)和多例模式,
scope="singleton" 單例模式的配置
scope="prototype" 多例模式的配置
注意:
-
singleton:默認值,單例,專案全域記憶體中只有一個物件,一般在使用Spring的時候保持默認值即可
-
prototype:原型的意思,在這里是多例,每參考或者getBean一次,Spring框架就回傳一個新的物件,比如SqlSession這個特殊的物件
<!-- 配置HappyComponent類的物件,放在物件容器中 --> <bean id="happyComponent" class="com.atguigu.ioc.HappyComponent" scope="singleton"></bean>
(4)通過IOC容器獲取物件(不強轉)
@Test public void testSpringIOCNoCast(){ ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); //方式一:context物件的方法,獲取容器中的物件:getBean(要獲取的物件的類的class物件) HappyComponent happyComponent = context.getBean(HappyComponent.class); happyComponent.doWork(); //方式二:getBean("組態檔中的id屬性值",要獲取的物件,類的class物件) //HappyComponent happyComponent1 = context.getBean("happyComponent", HappyComponent.class); //happyComponent1.doWork(); }
注意:SpringIOC物件容器的本質:Map集合ConcurrentHashMap
(5)IOC容器中的生命周期
init-method="initMethod" destroy-method="destroyMethod"
- init-method:物件初始化呼叫的方法
- destroy-method:物件銷毀之前呼叫的方法
(5-1)HappyComponent類中添加兩個方法initMethod()、destory()
public class HappyComponent { /* 自己定義方法:宣告周期的初始化方法 initMethod() Spring框架創建物件,呼叫方法 initMethod * */ public void initMethod(){ System.out.println("物件初始化方法"); } public void destory(){ System.out.println("物件銷毀的方法"); } public void doWork() { System.out.println("component do work ..."); } }
(5-2) ApplicationContext.xml檔案中添加呼叫初始化、銷毀方法的屬性
<!-- 配置物件的生命周期: 屬性:init-method,配置方法名即可 屬性:destory-method,配置方法名即可 --> <bean id="happyComponent" class="com.atguigu.ioc.HappyComponent" scope="singleton" init-method="initMethod" destroy-method="destory"></bean>
(5-2)測驗方法
銷毀方法,只有銷毀ApplicationContext物件才會銷毀
@Test public void testSpringIOCLife(){ ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); HappyComponent happyComponent = context.getBean(HappyComponent.class); happyComponent.doWork(); //銷毀容器中的物件,關閉容器 ClassPathXmlApplicationContext context1 =(ClassPathXmlApplicationContext) context; context1.close(); }
第三章、依賴注入(DI)
- dependency Inject(依賴注入的意思)
- IOC和DI的區別
(1) IOC和DI是一個事情,只是描述的角度不同
(2) DI 是 IOC 的另一種表述方式:即組件以一些預先定義好的方式(例如:setter 方法)接受來自于容器的資源注入,相對于IOC而言,這種表述更直接,
- 結論是:IOC 就是一種反轉控制的思想, 而 DI 是對 IOC 的一種具體實作,
1. set方法注入
(1)創建物件(get和set方法用lombok插件代替)
@Data public class HappyComponent { private String componentName; }
(2)將物件注入spring中
<!-- 配置物件,放在spring框架IOC容器中 利用set方法,為componentName欄位賦值 bean標簽的子標簽:property 為欄位賦值 property標簽的屬性:name set方法名,去掉set字母,字母小寫 property標簽的屬性:value 欄位值 --> <bean id="happyComponent" class="com.atguigu.ioc.HappyComponent"> <property name="componentName" value="張三"/> </bean>
(3)測驗依賴注入,set方法注入
@Test public void testDiSet(){ ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); HappyComponent happyComponent = context.getBean(HappyComponent.class); System.out.println("componentName = " + happyComponent.getComponentName()); }
2. set方法注入——講一個物件作為另一個物件的一個欄位注入
(1)創建物件
@Data public class HappyMachine { private String machineName; //將HappyComponent物件作為該物件的一個屬性 private HappyComponent happyComponent; }
(2)講物件注入spring中
<!-- 為一個類的欄位,注入另一個類的物件的時候,property標簽不能使用value屬性 使用另個一個屬性 ref = '另一個物件的id值' --> <bean id="machine" class="com.atguigu.ioc.HappyMachine"> <property name="machineName" value="Java虛擬機"/> <property name="happyComponent" ref="happyComponent"/> </bean> <bean id="happyComponent" class="com.atguigu.ioc.HappyComponent"> <property name="componentName" value="張三"/> </bean>
(3)測驗
/* 測驗一個型別,作為另一個型別的欄位出現 set方法注入 * */ @Test public void testDiSet2(){ ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); HappyMachine happyMachine = context.getBean(HappyMachine.class); System.out.println("happyMachine = " + happyMachine); }
3. 構造方法注入
(1)創建類
@Data @AllArgsConstructor @NoArgsConstructor public class Person { private Integer id; private Double money; private String name; }
(2)將Person物件注入Spring組態檔中
<!-- 配置Person物件 構造方法:將資料,注入到類的欄位中 標簽:constructor-arg name屬性:表示構造方法的引數名 --> <bean class="com.atguigu.ioc.Person" id="person"> <constructor-arg name="id" value="1"/> <constructor-arg name="money" value="199.0"/> <constructor-arg name="name" value="王五"/> </bean>
(3)測驗
/* 測驗依賴注入 構造方法 * */ @Test public void DiConstructor(){ ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); Person person = context.getBean(Person.class); System.out.println("person = " + person); }
4. 特殊值的注入處理
null值
(1)創建類
@Data public class ValueClass { private String commonValue; }
(2)指定commonValue欄位為控制
<bean class="com.atguigu.ioc.ValueClass" id="valueClass"> <!--set方法注入資料,欄位名commonValue 賦值特殊值,null 常量--> <property name="commonValue"> <null/> </property> </bean>
(3)測驗,結果報空指標例外
@Test public void testDiValue(){ ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); ValueClass valueClass = context.getBean(ValueClass.class); boolean b = valueClass.getCommonValue().equals("abc"); System.out.println(b);//報空指標例外 }
5. 復雜資料型別的注入(陣列、List、Set、Map、Properties)
(1)創建類
@Data public class ComplexValue { private String[] myStrs; private List<String> myList; private Set<String> mySet; private Map<String,String> myMap; private Properties myPro; }
(2)講物件注入Spring組態檔中
<!-- 配置物件ComplexValue:物件中欄位進行資料注入 欄位都是容器 --> <bean class="com.atguigu.ioc.ComplexValue" id="complexValue"> <!--set方法注入--> <property name="myStrs"> <!--輸入陣列,property標簽子標簽 array 輸入的資料是陣列容器--> <array> <!--注入陣列元素--> <value>java</value> <value>c++</value> <value>mysql</value> <value>Machine</value> </array> </property> <!--注入list集合--> <property name="myList"> <list> <value>java - list</value> <value>C++ - list</value> <value>python - list</value> <value>c - list</value> </list> </property> <!--注入set集合,set集合是不重復元素--> <property name="mySet"> <!--property的子標簽 set--> <set> <value>a</value> <value>b</value> <value>c</value> <value>d</value> </set> </property> <!--注意Map集合--> <property name="myMap"> <map> <!-- Map子標簽 entry entry標簽的屬性 key = Map的鍵 entry標簽的屬性 value = https://www.cnblogs.com/pdjdghrs/archive/2021/11/02/Map的值 --> <entry key="Eden" value="伊甸園"/> <entry key="survivor0" value="幸存者0"/> <entry key="survivor1" value="幸存者1"/> </map> </property> <!--注入Properties集合,Map的實作類,鍵值對,無序的哈希表,執行緒安全--> <property name="myPro"> <!--property子標簽props--> <props> <!-- prop配置單個鍵值對 --> <prop key="Eden">伊甸園</prop> <prop key="survivor0">幸存者0</prop> <prop key="survivor1">幸存者1</prop> </props> </property> </bean>
(3)測驗
補充知識點:
Properties類
方法:Set<String> stringPropertyNames():回傳此屬性串列中的鍵集
String getProperty(String key):根據鍵回傳值
/* 測驗依賴注入,輸入陣列容器 * */ @Test public void testDiArray(){ ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); ComplexValue complexValue = context.getBean(ComplexValue.class); //測驗依賴注入,輸入陣列容器 String[] myStrs = complexValue.getMyStrs(); for (String s : myStrs) { System.out.println("s = " + s); } //測驗依賴注入,注入List集合 List<String> myList = complexValue.getMyList(); System.out.println("myList = " + myList); //測驗依賴注入,注入Set集合 Set<String> mySet = complexValue.getMySet(); System.out.println("mySet = " + mySet); //測驗依賴注入,注入Map集合 Map<String, String> myMap = complexValue.getMyMap(); System.out.println("myMap = " + myMap); //測驗依賴注入,注入Properties Properties myPro = complexValue.getMyPro(); System.out.println("myPro = " + myPro); //myPro集合物件stringPropertyNames() 將集合的鍵,存盤到Set集合 == Map的方法keySet() Set<String> set = myPro.stringPropertyNames(); for (String s : set) { String property = myPro.getProperty(s); System.out.println(s+" = " + property); } }
(4)運行結果
s = java s = c++ s = mysql s = Machine myList = [java - list, C++ - list, python - list, c - list] mySet = [a, b, c, d] myMap = {Eden=伊甸園, survivor0=幸存者0, survivor1=幸存者1} myPro = {survivor0=幸存者0, survivor1=幸存者1, Eden=伊甸園} survivor0 = 幸存者0 survivor1 = 幸存者1 Eden = 伊甸園
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/345515.html
標籤:其他
上一篇:貪心法(一):貪心法的基本思想
