Spring框架總結(三)——bean標簽和依賴注入


一、bean 標簽和管理對象細節


 

1.1 bean 標簽

作用:

  用於配置對象讓spring來創建的。

  默認情況下它調用的是類中的無參構造函數。如果沒有無參構造函數則不能創建成功。

屬性:

  id:給對象在容器中提供一個唯一標識。用於獲取對象。

  class:指定類的權限定類名。用於反射創建對象。默認情況下調用無參構造函數。

  scope:指定對象的作用范圍。

    * singleton:默認值,單例的。

    * prototype:多例的

  init-method:指定類中的初始化方法名稱。

  destory-method:指定類中銷毀方法名稱。

1.2 bean的作用范圍和生命周期

單列對象:scope="singleton"

  一個應用只有一個對象的實例。它的作用范圍就是整個引用。

  生命周期:

    對象出生:當應用加載時,創建容器時,對象就被創建了。

    對象活着:只有容器在,對象一直活着。

    對象死亡:當應用卸載,銷毀容器時,對象就被銷毀了。

多例對象:scope="prototype"

  每次訪問對象時,都會重新創建對象實例。

  生命周期:

    對象出生:當使用對象時,創建新的對象實例。

    對象活着:只要對象在使用中,就一直活着。

    對象死亡:當對象長時間不用時,被java的垃圾回收器回收了。

演示:單例和多例對象

第一步:編寫IUserService接口

 

1 package com.justnow.service;
2 
3 public interface IUserService {
4     public void findAll();
5 }

 

第二步:編寫UserServiceImpl實現類

 1 package com.justnow.service.impl;
 2 
 3 import com.justnow.service.IUserService;
 4 
 5 public class UserServiceImpl implements IUserService {
 6 
 7     public void findAll() {
 8         System.out.println("假裝打印了數據庫中的所有數據");
 9     }
10 }

第三步:編寫spring配置文件

1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4        xsi:schemaLocation="http://www.springframework.org/schema/beans
5        http://www.springframework.org/schema/beans/spring-beans.xsd">
6     <!--配置 service -->
7     <bean id="userService" class="com.justnow.service.impl.UserServiceImpl" scope="singleton"/>
8 </beans>

這里配置scope為單例對象

第四步:測試

 1 package com.justnow.test;
 2 
 3 import com.justnow.service.IUserService;
 4 import org.junit.Test;
 5 import org.springframework.context.support.ClassPathXmlApplicationContext;
 6 
 7 public class Test01 {
 8     @Test
 9     public void testBean(){
10         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
11         IUserService userService = (IUserService) context.getBean("userService");
12         IUserService userService1 = (IUserService) context.getBean("userService");
13         System.out.println(userService);
14         System.out.println(userService1);
15     }
16 }

單例測試結果:

 

 

 

 

userService和userService2,打印出來的結果是一致的!

雙例測試結果:

修改scope為"prototype"

 

 

 

1.3 實例化bean的三種方式

第一種方式:使用默認無參構造函數

會根據默認無參構造函數來創建類對象。如果bean中沒有默認無參構造函數,將會創建失敗。

如:

1 <bean id="userService" class="com.justnow.service.impl.UserServiceImpl" />

此時UserServiceImpl中必須有無參的構造函數。

第二種方式:spring管理靜態工廠-使用靜態工廠的方法創建對象

模擬一個靜態工廠,創建業務層實現類

 1 package com.justnow.factory;
 2 
 3 import com.justnow.service.IUserService;
 4 import com.justnow.service.impl.UserServiceImpl;
 5 
 6 public class StaticFactory {
 7     public static IUserService createUserService(){
 8         return new UserServiceImpl();
 9     }
10 }

bean的配置,使用StaticFactory類中的靜態方法createUserService創建對象,並存入spring容器:

id 屬性:指定bean的id,用於從容器中獲取

class屬性:指定靜態工廠的全限定類名

factory-method 屬性:指定生產對象的靜態方法

1 <bean id="userService" class="com.justnow.factory.StaticFactory" factory-method="createUserService" />

第三種方式:spring管理實例工廠-使用實例工廠的方法創建對象

先把工廠的創建交給spring來管理。然后在使用工廠的bean來調用里面的方法

factory-bean屬性:用來指定實例工廠beand的id。

factory-method屬性:用於指定實例工廠中創建對象的方法。

模擬一個實例工廠,創建業務層實現類

此工廠創建對象,必須現有工廠實例對象,再調用方法

 1 package com.justnow.factory;
 2 
 3 import com.justnow.service.IUserService;
 4 import com.justnow.service.impl.UserServiceImpl;
 5 
 6 /**
 7  * 模擬一個實例工廠,創建業務層實現類
 8  * 此工廠創建對象,必須有工廠實例對象,再調用方法
 9  */
10 public class InstanceFactory {
11     public IUserService createUserService(){
12         return new UserServiceImpl();
13     }
14 }

bean的配置文件

    <!--第三種方式,spring管理實例工廠,使用實例工廠的方法創建對象-->
    <bean id="instanceFactory" class="com.justnow.factory.InstanceFactory"/>
    <bean id="userService" factory-bean="instanceFactory" factory-method="createUserService" />

https://github.com/justn0w/javawebdemo/tree/master/spring/Spring_demo2 

d20c371406409b204c554c0a41c91ad5b6b86de1

二、spring的依賴注入

2.1 什么是依賴注入:

依賴注入:Dependency Injection。它是spring框架核心IoC的具體實現。

我們的程序在編寫時,通過控制反轉,把對象的創建交給了spring,但是在代碼中不可能出現沒有依賴的情況。IoC解耦只是降低他們的依賴關系。

但不會消除。例如:我們的業務層仍會調用持久層的方法。簡單的說就是spring框架把持久層對象傳入業務層,而不用我們自己去獲取。

2.2 通過構造函數實現依賴注入

使用類中的構造函數,給成員變量賦值。賦值操作是由spring框架來為我們注入的。

UserServiceImpl實現類:

該類共有三個屬性,分別是name,age,birthday;

 1 package com.justnow.service.impl;
 2 
 3 import com.justnow.service.IUserService;
 4 
 5 import java.util.Date;
 6 
 7 public class UserServiceImpl implements IUserService {
 8 
 9     private String name;
10     private Integer age;
11     private Date birthdy;
12 
13     public UserServiceImpl() {
14     }
15 
16     public UserServiceImpl(String name, Integer age, Date birthdy){
17         this.name = name;
18         this.age = age;
19         this.birthdy = birthdy;
20     }
21 
22     public void save(){
23         System.out.println(name+","+age+","+birthdy);
24     }
25 
26 /*    public void findAll() {
27         System.out.println("假裝打印了數據庫中的所有數據");
28     }*/
29 }

在配置文件中賦值:

applicationContext.xml

1     <!--通過構造函數實現依賴注入-->
2     <bean id="userService" class="com.justnow.service.impl.UserServiceImpl" >
3         <constructor-arg name="name" value="張三"></constructor-arg>
4         <constructor-arg name="age" value="18"></constructor-arg>
5         <constructor-arg name="birthdy" ref="now"></constructor-arg>
6     </bean>
7     <bean id="now" class="java.util.Date" />

使用構造函數的方式,給service中的屬性賦值

要求:類中需要提供一個對應參數列表的構造函數

標簽:constructor-arg

  屬性:index:指定參數在構造函數列表的索引位置

     type:指定參數在構造函數中的數據類型

     name:指定參數在構造函數中的名稱

     value:給name屬性賦值,前提是基本數據類型和String類型

     ref:同樣的是給name賦值,但是該值是bean類型,必須在配置文件中配置。如上例中的id為now的bean標簽

本小節代碼:

https://github.com/justn0w/javawebdemo/tree/master/spring/Spring_demo2

2e64f8d7cf0a7a1f710e8abfc3d9707653b5063a

2.2 set 方法注入

 在UserServiceImpl實現類中,設置屬性的set的方法即可代碼,如下:

 1 package com.justnow.service.impl;
 2 
 3 import com.justnow.service.IUserService;
 4 
 5 import java.util.Date;
 6 
 7 public class UserServiceImpl implements IUserService {
 8 
 9     private String name;
10     private Integer age;
11     private Date birthdy;
12 
13     //set 方法注入
14     public void setName(String name) {
15         this.name = name;
16     }
17 
18     public void setAge(Integer age) {
19         this.age = age;
20     }
21 
22     public void setBirthdy(Date birthdy) {
23         this.birthdy = birthdy;
24     }
25 
26     public void save(){
27         System.out.println(name+","+age+","+birthdy);
28     }
29     
30 }

同時還需要修改spring的配置文件

 1     <!--通過set方法實現依賴注入-->
 2     <!-- 通過配置文件給 bean 中的屬性傳值:使用 set 方法的方式
 3     涉及的標簽:
 4         property
 5     屬性:
 6         name:找的是類中 set 方法后面的部分
 7         ref:給屬性賦值是其他 bean 類型的
 8         value:給屬性賦值是基本數據類型和 string 類型的
 9     實際開發中,此種方式用的較多。
10 -->
11     <bean id="userService" class="com.justnow.service.impl.UserServiceImpl">
12         <property name="name" value="test"/>
13         <property name="age" value="21"/>
14         <property name="birthdy" ref="now" />
15     </bean>
16 
17     <bean id="now" class="java.util.Date" />

測試結果:

 

 

 

 https://github.com/justn0w/javawebdemo/tree/master/spring/Spring_demo2

fe6038b18cff7d32c1b4515bf53bea9c8b0bdd0e

2.2 使用p名稱空間注入數據

在xml中導入p名稱空間,使用p:propertyName來注入數據,本質仍然是調用類中的set方法實現注入功能。

所以,UserServiceIpml實現類,不需要改變。只需要修改spring的配置文件即可

第一步:修改xml的命名空間,即添加p命名空間

添加了一句:

xmlns:p="http://www.springframework.org/schema/p"

 

 

 

第二步:在bean中使用p標簽給屬性賦值

1 <bean id="userService" class="com.justnow.service.impl.UserServiceImpl" p:name="testp" p:age="23" p:birthdy-ref="now"/>
2 <bean id="now" class="java.util.Date" />

測試結果:

 

 

 47e50fff82f0cee3155226f620a00989da3828a6

2.3 注入集合屬性

考慮到某些情況下需要一些類型為集合的屬性,接下來就演示下,如何注入集合屬性的。其本質還是通過set方法注入屬性的

第一步:在實現類中添加數組、List、set、Map、Properties等數據類型的屬性。

 1 package com.justnow.service.impl;
 2 
 3 import com.justnow.service.IUserService;
 4 
 5 import java.util.*;
 6 
 7 public class UserServiceImpl2 implements IUserService {
 8 
 9     private String[] myStrs;
10     private List<String> myList;
11     private Set<String> mySet;
12     private Map<String, String> myMap;
13     private Properties myProps;
14 
15     public void setMyStrs(String[] myStrs) {
16         this.myStrs = myStrs;
17     }
18 
19     public void setMyList(List<String> myList) {
20         this.myList = myList;
21     }
22 
23     public void setMySet(Set<String> mySet) {
24         this.mySet = mySet;
25     }
26 
27     public void setMyMap(Map<String, String> myMap) {
28         this.myMap = myMap;
29     }
30 
31     public void setMyProps(Properties myProps) {
32         this.myProps = myProps;
33     }
34 
35 
36     public void save() {
37         System.out.println(Arrays.toString(myStrs));
38         System.out.println(myList);
39         System.out.println(mySet);
40         System.out.println(myMap);
41         System.out.println(myProps);
42     }
43 }

第二步:修改spring配置文件

  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <beans xmlns="http://www.springframework.org/schema/beans"
  3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4        xmlns:p="http://www.springframework.org/schema/p"
  5        xsi:schemaLocation="http://www.springframework.org/schema/beans
  6        http://www.springframework.org/schema/beans/spring-beans.xsd">
  7     <!--配置 service -->
  8 <!-- 第一種方式,使用默認無參構造函數
  9     <bean id="userService" class="com.justnow.service.impl.UserServiceImpl" scope="prototype"/>
 10 -->
 11     <!--第二種方式,spring管理靜態工廠-使用靜態工廠的方法對象創建-->
 12 <!--
 13     <bean id="userService" class="com.justnow.factory.StaticFactory" factory-method="createUserService" />
 14 -->
 15     <!--第三種方式,spring管理實例工廠,使用實例工廠的方法創建對象-->
 16 <!--
 17     <bean id="instanceFactory" class="com.justnow.factory.InstanceFactory"/>
 18     <bean id="userService" factory-bean="instanceFactory" factory-method="createUserService" />
 19 -->
 20 
 21     <!--通過構造函數實現依賴注入-->
 22 <!--
 23     <bean id="userService" class="com.justnow.service.impl.UserServiceImpl" >
 24         <constructor-arg name="name" value="張三"></constructor-arg>
 25         <constructor-arg name="age" value="18"></constructor-arg>
 26         <constructor-arg name="birthdy" ref="now"></constructor-arg>
 27     </bean>
 28     <bean id="now" class="java.util.Date" />
 29 -->
 30     <!--通過set方法實現依賴注入-->
 31     <!-- 通過配置文件給 bean 中的屬性傳值:使用 set 方法的方式
 32     涉及的標簽:
 33         property
 34     屬性:
 35         name:找的是類中 set 方法后面的部分
 36         ref:給屬性賦值是其他 bean 類型的
 37         value:給屬性賦值是基本數據類型和 string 類型的
 38     實際開發中,此種方式用的較多。
 39 
 40     <bean id="userService" class="com.justnow.service.impl.UserServiceImpl">
 41         <property name="name" value="test"/>
 42         <property name="age" value="21"/>
 43         <property name="birthdy" ref="now" />
 44     </bean>
 45 
 46     <bean id="now" class="java.util.Date" />
 47 -->
 48     <!--使用p命名空間-->
 49 <!--
 50     <bean id="userService" class="com.justnow.service.impl.UserServiceImpl" p:name="testp" p:age="23" p:birthdy-ref="now"/>
 51     <bean id="now" class="java.util.Date" />
 52 -->
 53     <!-- 注入集合數據
 54         List 結構的:
 55             array,list,set
 56         Map 結構的
 57             map,entry,props,prop
 58 -->
 59     <bean id="userService" class="com.justnow.service.impl.UserServiceImpl2">
 60         <!-- 在注入集合數據時,只要結構相同,標簽可以互換 -->
 61         <!-- 給數組注入數據 -->
 62         <property name="myStrs">
 63             <array>
 64                 <value>AAA</value>
 65                 <value>BBB</value>
 66                 <value>CCC</value>
 67             </array>
 68         </property>
 69         <!-- 注入 list 集合數據 -->
 70         <property name="myList">
 71             <list>
 72                 <value>AAA</value>
 73                 <value>BBB</value>
 74                 <value>CCC</value>
 75             </list>
 76         </property>
 77         <!-- 注入 set 集合數據 -->
 78         <property name="mySet">
 79             <set>
 80                 <value>AAA</value>
 81                 <value>BBB</value>
 82                 <value>CCC</value>
 83             </set>
 84         </property>
 85         <!-- 注入 Map 數據 -->
 86         <property name="myMap">
 87             <props>
 88                 <prop key="testA">aaa</prop>
 89                 <prop key="testB">bbb</prop>
 90             </props>
 91         </property>
 92         <!-- 注入 properties 數據 -->
 93         <property name="myProps">
 94             <map>
 95                 <entry key="testA" value="aaa"></entry>
 96                 <entry key="testB">
 97                     <value>bbb</value>
 98                 </entry>
 99             </map>
100         </property>
101     </bean>
102 </beans>

77a345e6da51295e1aa4c5e8c25038e23da3f6ec

總結:


 

1、這些內容在將來的開發過程中會很少用到,但是,還是梳理一下。

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM