今天學習了spring框架,剛剛入門簡單的了解了spring并學習了bean的注入IOC:IOC(Inversion of Control,控制反轉)不是什么技術,而是一種設計思想,它的目的是指導我們設計出更加松耦合的程式,
引入:
使用簡單代碼來實作推演 ,創建一個maven專案,開始我們的推演
創建一個bean類即常說的物體類如下:

我們創建一個測驗類 springTest,在測驗類中操作,怎么樣來獲取Student類中 的資訊呢(student類中有構造方法,無參,有參,有get,set方法,有studay() 方法 等等)
我們要怎么樣來獲取物件呢:
1.直接獲取:
@Test public void springTest() { Student student = new Student(); student.getStudy(); /* * 輸出 學生在學習 * */ }
上述代碼是否顯得太low了,因為假若有n個類使用這個對像,我們要在每一個類中new,假若你要修改,這樣的一個工程量會有點大,
2.工具類獲取:

我們創建工具類來減少耦合性,在修改維護時只要修改工具類就行 代碼呼叫:
@Test public void springTest02() { Student stu = StudentBean.getStu(); stu.getStudy(); /* * 輸出 學生在學習 * */ }
這樣就減少了一定的耦合性能,但在實際運用中,我們只可能只有一個物體類嘛當然不可能,如何提升性能并減少代碼的耦合性呢
我們采用組態檔的方法建一個 beans.properties 存放bean的組態檔,并多創建一個物體類user

重新再創建一個工具類BeanFactroy來撰寫我們的最終代碼:
public class BeanFactory { // 創建map集合存盤物件 private static Map<String, Object> beanMap = new HashMap<String, Object>(); /* * 在類初始化時讀取beans組態檔中所有的bean類存盤到map集合中 * */ static { try { ResourceBundle beans = ResourceBundle.getBundle("beans");// 讀取beans組態檔 Enumeration<String> keys = beans.getKeys(); // 獲取所有key值 while (keys.hasMoreElements()) { String key = keys.nextElement(); // 獲取每個key String className = beans.getString(key); // 獲取value Class<?> aClass = Class.forName(className); // 通過反射得到該類 Object o = aClass.newInstance(); // 通過反射機制創建該類物件 beanMap.put(key, o); // 將k v值存入beanMap集合中 } } catch (Exception e) { e.printStackTrace(); } } /* 創建靜態方法供外界呼叫 * */ public static Object getBean(String beanName) { return beanMap.get(beanName); } }
上面是工具類,下面是測驗:
@Test public void springTest03() { User user = (User) BeanFactory.getBean("user"); user.getStudy(); /* * 輸出 我在學習 * */ } @Test public void springTest04() { Student stu = (Student) BeanFactory.getBean("student"); stu.getStudy(); /* * 輸出 學生在學習 * */ }
上面的實體簡單的展示來如何減少耦合性,最終下來,在管理物件時,我們只需要修改beans.properties 檔案即可,更加方便管理下面進入spring的ioc容器使用
Bean容器注入:
第一步導包:
<properties> <spring.version>5.2.9.RELEASE</spring.version> <junit-version>5.6.2</junit-version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>${junit-version}</version> </dependency> </dependencies>
第二步創建組態檔 applicationContext.xml (認準下面的步驟)

完成后如下:

開始撰寫:
通過構造方法獲取物件:

測驗代碼:
/* * 讀取app.xml檔案 抽取出來 * */ private ApplicationContext ac = new ClassPathXmlApplicationContext("app.xml"); @Test public void springTest05() { User user1 = (User) ac.getBean("user1"); // user1與app.xml中bean里面的id值相對應 user1.getStudy(); // 列印 我在學習 }
讀取xml方法:
- ClassPathXmlApplicationContext: 從classpath目錄讀取組態檔
- FileSystemXmlApplicationContext: 從檔案系統或者url中讀取組態檔
- AnnotationConfigApplicationContext:當我們使用注解配置容器物件時,需要使用此類來創建 spring 容器,它用來讀取注解,
使用前面的工廠來獲取物件:

測驗代碼:
@Test public void springTest06() { User user1 = (User) ac.getBean("user2"); // user1與app.xml中bean里面的id值相對應 user1.getStudy(); // 列印 我在學習 }
在操作這里的時候我將BeanFactory修改了一點:
public class BeanFactory { private String beanName; private static Map<String, Object> beansObjectHashMap = new HashMap<String, Object>(); public BeanFactory() { } public BeanFactory(String beanName) { this.beanName = beanName; } /* * 采用靜態代碼塊,在程式開始時,就將所有的物件存在beansObjectHashMap map集合中,使用時直接呼叫 * */ static { try { ResourceBundle beans = ResourceBundle.getBundle("beans"); Enumeration<String> keys = beans.getKeys(); while (keys.hasMoreElements()) { String key = keys.nextElement(); String className = beans.getString(key); Class<?> aClass = Class.forName(className); Object o = aClass.newInstance(); beansObjectHashMap.put(key, o); } } catch (Exception e) { e.printStackTrace(); } } // 采用組態檔獲取物件 只能 獲取一個 public static Object getBeanUser(String beanName) { try { ResourceBundle bundle = ResourceBundle.getBundle("beans"); String string = bundle.getString(beanName); Class<?> aClass = Class.forName(string); Object o = aClass.newInstance(); return o; } catch (Exception e) { e.printStackTrace(); return null; } } /* * 當有多個物體類時 封裝一個map集合回傳 * */ public static Object getBeanMap(String beanName) { return beansObjectHashMap.get(beanName); } /* public Object getBeanMap() { return beansObjectHashMap.get(this.beanName); }*/ }
Bean單例與多例:
<!-- Bean單例與多例,在bean容器中添加有個scope屬性,singleton代表單例 prototype 代表多例,單例獲取的物件地址值是相同的,多例是不同的 呼叫案例就一樣的不寫了 --> <bean id="user3" class="com.code.spring01.entity.User" scope="singleton"></bean> <!-- 單例 --> <bean id="user4" class="com.code.spring01.entity.User" scope="prototype"></bean> <!-- 多例 --> <!-- 單例生命周期:容器創建時,就創建物件;容器摧毀時,就摧毀物件, 多例生命周期:getBean方法被呼叫時,創建物件,物件銷毀與spring無關,等待垃圾回識訓制回收 -->
set方法注入:
<!-- 使用set注入時,bean類中需存在get set 方法 set 方法注入 property和constructor-arg 使用時的區別 (不用在意順序)property注入時可以單個屬性的注入,即想寫幾個屬性就寫幾個(不能超過) constructor-arg 注入時,需全部屬性都注入,否則會報錯 --> <bean id="stu2" class="com.code.spring01.entity.Student"> <property name="age" value="19"></property> <property name="name" value="張三"></property> </bean> <!-- <bean id="stu2" > <constructor-arg name="name" value="https://www.cnblogs.com/2979100039-qq-con/archive/2020/10/12/張三"></constructor-arg> </bean>--> <!-- set 注入的簡寫 方式 --> <bean id="stu3" class="com.code.spring01.entity.Student" p:name="王五" p:pwd="123" p:age="31" p:sex="男"/>
集合屬性注入:
物體類:
public class Tec { // 基本屬性 private Integer id; private String username; private String password; private Address address; //list set array private String[] str; private List<String> list; private Set<String> set; //map properties private Map<String,String> map; private Properties properties; // 省略了set方法
bean注入:
<bean id="user" class="com.hopu.ioc.User"> <property name="str"> <array> <value>EE</value> <value>FF</value> </array> </property> <property name="list"> <list> <value>AA</value> <value>BB</value> </list> </property> <property name="set"> <set> <value>CC</value> <value>DD</value> </set> </property> <property name="map"> <map> <entry key="GG" value="gg"/> <entry key="HH" value="hh"/> </map> </property> <property name="properties"> <props> <prop key="II">ii</prop> <prop key="JJ">jj</prop> </props> </property> </bean>
Bean的多模塊注入:
當專案過于龐大時,為了開發便于維護和可讀性,我們可以將bean組態檔模塊化,采用匯入模塊方式優化管理
<!-- 在app.xml中匯入app2.xml檔案 --> <import resource="app2.xml"/>
注解注入:
這個我沒學,在百度上看了,簡單模仿這操作一番:
@Component("admin") // 等同于bean id="admin" ></bean>
@Scope(scopeName = "singleton") // 限制創建的為單例物件
//@Scope(scopeName = "prototype") // 限制創建的為多例物件
public class Admin {
private String name;
private String color;
public Admin(String name, String color) {
this.name = name;
this.color = color;
}
public Admin() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return color;
}
public void setAge(String color) {
this.color = color;
}
@Override
public String toString() {
return "Admin{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
'}';
}
}
私有成員變數注入:
@Value("BMW")
private String name;
@Value("Red")
private String color;
set方法注入:
@Value("BMW")
public void setName(String name) {
this.name = name;
}
@Value("Red")
public void setColor(String color) {
this.color = color;
}
在使用時當然是bean容器更加方便管理一些,代碼耦合性也低
個人學習,內容簡略,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/169645.html
標籤:其他
