Spring-IoC的注入方式及注入不同的數據類型

關於Spring-IoC的簡單使用參考:
Spring-IoC的簡單使用

1、通過set方法注入不同數據類型

  • 測試類代碼(set方式注入的屬性一定要加set方法)
/**通過set方法注入示例*/
public class IoC_By_Set {
    /**注入Integer類型參數*/
    private Integer id;
    /**注入String類型參數*/
    private String name;
    /**注入實體Bean*/
    private User user;
    /**注入數組*/
    private Object[] array;
    /**注入List集合*/
    private List<Object> list;
    /**注入Set集合*/
    private Set<Object> set;
    /**注入Map鍵值對*/
    private Map<Object, Object> map;
    /**注入properties類型*/
    private Properties properties;
    /**注入空字符串*/
    private String emptyValue;
    /**注入null值*/
    private String nullValue = "";

    /**檢測注入的屬性是否全部正確*/
    public boolean checkAttr() {
        if(id == null) {
            return false;
        }else {
            System.out.println("id:" + id);
        }
        System.out.println("--------------------------");
        if(name == null) {
            return false;
        }else {
            System.out.println("name:" + name);
        }
        System.out.println("--------------------------");
        if(user == null) {
            return false;
        }else {
            System.out.println("Bean:" + user.getId() + "|" + 
                    user.getUserName() + "|" + user.getPassWord());
        }
        System.out.println("--------------------------");
        if(array == null) {
            return false;
        }else {
            System.out.println("array:");
            for (Object object : array) {
                System.out.println(object.toString());
            }
        }
        System.out.println("--------------------------");
        if(list == null) {
            return false;
        }else {
            System.out.println("list:");
            for (Object object : list) {
                System.out.println(object.toString());
            }
        }
        System.out.println("--------------------------");
        if(set == null) {
            return false;
        }else {
            System.out.println("set:");
            for (Object object : set) {
                System.out.println(object.toString());

            }
        }
        System.out.println("--------------------------");
        if(map == null) {
            return false;
        }else {
            Set<Entry<Object, Object>> set = map.entrySet();
            System.out.println("map:");
            for (Entry<Object, Object> entry : set) {
                System.out.println(entry.getKey() + "|" + entry.getValue());
            }
        }
        System.out.println("--------------------------");
        if(properties == null) {
            return false;
        }else {
            Set<Entry<Object, Object>> set = properties.entrySet();
            System.out.println("properties:");
            for (Entry<Object, Object> entry : set) {
                System.out.println(entry.getKey() + "|" + entry.getValue());
            }
        }
        System.out.println("--------------------------");
        if(!"".equals(emptyValue))
            return false;
        System.out.println("--------------------------");
        if(!(null == nullValue))
            return false;
        System.out.println("--------------------------");
        System.out.println("全部正確!!!");
        return true;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public void setArray(Object[] array) {
        this.array = array;
    }

    public void setList(List<Object> list) {
        this.list = list;
    }

    public void setSet(Set<Object> set) {
        this.set = set;
    }

    public void setMap(Map<Object, Object> map) {
        this.map = map;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    public void setEmptyValue(String emptyValue) {
        this.emptyValue = emptyValue;
    }

    public void setNullValue(String nullValue) {
        this.nullValue = nullValue;
    }

}
  • applicationContext.xml配置
    <!-- set方式注入 -->
    <bean id="ioC_By_Set" class="com.bc.ioc.demo01.IoC_By_Set">
        <!-- 注入id屬性 -->
        <property name="id" value="1"/>
        <!-- 使用<![CDATA[]]>標記處理XML特 殊字符 -->
        <property name="name">
            <!-- 也可以使用P&amp;G -->
            <value><![CDATA[P&G]]></value>
        </property>
        <!-- 定義內部Bean注入 -->
        <property name="user">
            <bean class="com.bc.pojo.User">
                <property name="id" value="1"/>
                <property name="userName" value="內部Bean"/>
                <property name="passWord" value="233"/>
            </bean>
        </property>
        <!-- 注入數組類型 -->
        <property name="array">
            <array>
                <!-- 定義數組元素 -->
                <value>array01</value>
                <value>array02</value>
                <value>array03</value>
            </array>
        </property>
        <!-- 注入List類型 -->
        <property name="list">
            <list>
                <!-- 定義list中元素 -->
                <value>list01</value>
                <value>list02</value>
                <value>list03</value>
            </list>
        </property>
        <!-- 注入Set類型 -->
        <property name="set">
            <set>
                <!-- 定義set中元素 -->
                <value>set01</value>
                <value>set02</value>
                <value>set03</value>
            </set>
        </property>
        <!-- 注入Map類型 -->
        <property name="map">
            <map>
                <!-- 定義map中的鍵值對 -->
                <entry>
                    <key>
                        <value>mapKey01</value>
                    </key>
                    <value>mapValue01</value>
                </entry>
                <entry>
                    <key>
                        <value>mapKey02</value>
                    </key>
                    <value>mapValue02</value>
                </entry>
            </map>
        </property>
        <!-- 注入properties類型 -->
        <property name="properties">
            <props>
                <!-- 定義properties中的鍵值對 -->
                <prop key="propKey1">propValue1</prop>
                <prop key="propKey2">propValue2</prop>
            </props>
        </property>
        <!-- 注入空字符串 -->
        <property name="emptyValue">
            <value></value>
        </property>
        <!-- 注入null值 -->
        <property name="nullValue">
            <null/>
        </property>
    </bean>
  • 測試代碼
public class IoC_Test {

    private ApplicationContext ctx;

    @Before
    public void load() {
        //讀取applicationContext.xml配置文件
        ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    }

    @Test
    public void SetTest() {
        IoC_By_Set ioc = (IoC_By_Set) ctx.getBean("ioC_By_Set");
        ioc.checkAttr();
    }
}
  • 控制檯結果:
id:1
--------------------------
name:P&G
--------------------------
Bean:1|內部Bean|233
--------------------------
array:
array01
array02
array03
--------------------------
list:
list01
list02
list03
--------------------------
set:
set01
set02
set03
--------------------------
map:
mapKey01|mapValue01
mapKey02|mapValue02
--------------------------
properties:
propKey2|propValue2
propKey1|propValue1
--------------------------
--------------------------
--------------------------
全部正確!!!

2、通過構造方法注入各種類型屬性

注意:使用JDK1.8版本請將spring相關jar包升級到4.x版本以上,否則不兼容構造方法注入

  • 測試類代碼
/** 通過構造方法注入示例 */
public class IoC_By_Constructor {

    private Integer id;
    private String name;
    private User user;
    private List<Object> list;

    public IoC_By_Constructor() {
    }

    public IoC_By_Constructor(Integer id, String name, User user,
            List<Object> list) {
        this.id = id;
        this.name = name;
        this.user = user;
        this.list = list;
    }

    /**檢查是否注入成功*/
    public boolean checkAttr() {
        if(id == null) {
            return false;
        }else {
            System.out.println("id:" + id);
        }
        System.out.println("----------------------------");
        if(name == null) {
            return false;
        }else {
            System.out.println("name:" + name);
        }
        System.out.println("----------------------------");
        if(user == null) {
            return false;
        }else {
            System.out.println("user:" + user.getId() + "|" + 
                    user.getUserName() + "|" + user.getPassWord());
        }
        System.out.println("----------------------------");
        if(list == null) {
            return false;
        }else {
            System.out.println("list:");
            for (Object object : list) {
                System.out.println(object.toString());
            }
        }
        System.out.println("----------------------------");
        System.out.println("全部正確!!!");
        return true;
    }
}
  • applicationContext.xml配置
    <!-- 構造方法注入 演示幾種類型-->
    <bean id="ioC_By_Constructor" class="com.bc.ioc.demo02.IoC_By_Constructor">
        <!-- 注入Integer屬性,可以選擇使用index指定參數位置,也可以選擇使用type指定參數類型 -->
        <constructor-arg index="0" value="1" type="java.lang.Integer"/>
        <!-- 注入字符串 -->
        <constructor-arg value="P&amp;G"/>
        <!-- 注入對象 -->
        <constructor-arg>
            <!-- 內建對象 -->
            <bean class="com.bc.pojo.User">
                <constructor-arg value="1"/>
                <constructor-arg value="構造內部Bean"/>
                <constructor-arg value="666"/>
            </bean>
        </constructor-arg>
        <!-- 注入集合 -->
        <constructor-arg>
            <list>
                <value>list01</value>
                <value>list02</value>
                <value>list03</value>
            </list>
        </constructor-arg>
    </bean>
  • 測試代碼:
public class IoC_Test {

    private ApplicationContext ctx;

    @Before
    public void load() {
        //讀取applicationContext.xml配置文件
        ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    }

    @Test
    public void constructorTest() {
        IoC_By_Constructor ioc = (IoC_By_Constructor) ctx.getBean("ioC_By_Constructor");
        ioc.checkAttr();
    }

}
  • 控制檯結果:
id:1
----------------------------
name:P&G
----------------------------
user:1|構造內部Bean|666
----------------------------
list:
list01
list02
list03
----------------------------
全部正確!!!

3、自動注入(自動裝配)

自動裝配雖然能節省一些代碼但是不推薦使用

  • 測試類代碼:
/**自動裝配注入*/
public class IoC_By_Auto {

    private User user;

    /**檢查是否注入成功*/
    public boolean checkAttr() {
        if(user == null) {
            return false;
        }else {
            System.out.println("user:" + user.getId() + "|" + 
                    user.getUserName() + "|" + user.getPassWord());
        }
        System.out.println("正確!!!");
        return true;
    }

    /**自動裝配的屬性需要設置set方法*/
    public void setUser(User user) {
        this.user = user;
    }

}
  • applicationContext.xml配置
    <!-- 被自動裝配獲取的bean -->
    <bean id="user" class="com.bc.pojo.User">
        <property name="id" value="1"/>
        <property name="userName" value="自動裝配"/>
        <property name="passWord" value="233"/>
    </bean>
    <!-- 自動裝配的bean
         autowire:byName 根據類的屬性名查找與之命名相同的id的bean進行裝配
                  byType 根據類的屬性類型查找唯一一個匹配類型的bean,如果有多個bean匹配則拋出異常
                  constructor 根據類的構造方法參數類型匹配對應的bean
                  no 默認,表示不使用自動裝配
                  default:由上級標籤<beans>的default-autowire屬性確定 -->
    <bean id="ioC_By_Auto" class="com.bc.ioc.demo03.IoC_By_Auto" autowire="byName"></bean>
  • 測試代碼
public class IoC_Test {

    private ApplicationContext ctx;

    @Before
    public void load() {
        //讀取applicationContext.xml配置文件
        ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    }

    @Test
    public void AutoTest() {
        IoC_By_Auto ioc = (IoC_By_Auto) ctx.getBean("ioC_By_Auto");
        ioc.checkAttr();
    }

}
  • 控制檯結果
user:1|自動裝配|233
正確!!!
  • 以上使用的是byName模式,其他模式配置代碼已經註明,不做測試。

4、使用P命名空間注入屬性

  • 測試類代碼
/**使用P命名空間注入*/
public class IoC_By_P {

    private Integer id;
    private String name;
    private User user;

    /**檢查是否注入成功*/
    public boolean checkAttr() {
        if(id == null) {
            return false;
        }else {
            System.out.println("id:" + id);
        }
        System.out.println("----------------------------");
        if(name == null) {
            return false;
        }else {
            System.out.println("name:" + name);
        }
        System.out.println("----------------------------");
        if(user == null) {
            return false;
        }else {
            System.out.println("user:" + user.getId() + "|" + 
                    user.getUserName() + "|" + user.getPassWord());
        }
        System.out.println("----------------------------");
        System.out.println("全部正確!!!");
        return true;
    }

    //使用P命名空間注入屬性需要設置set方法
    public void setId(Integer id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setUser(User user) {
        this.user = user;
    }

}
  • applicationContext.xml配置
    <!-- 使用P命名空間注入各種類型屬性 -->
    <bean id="user2" class="com.bc.pojo.User">
        <property name="id" value="1"/>
        <property name="userName" value="P"/>
        <property name="passWord" value="233"/>
    </bean>
    <bean id="ioC_By_P" class="com.bc.ioc.demo04.IoC_By_P" p:id="1" 
        p:name="命名空間" p:user-ref="user2"></bean>
  • 測試代碼
public class IoC_Test {

    private ApplicationContext ctx;

    @Before
    public void load() {
        //讀取applicationContext.xml配置文件
        ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    }

    @Test
    public void PTest() {
        IoC_By_P ioc = (IoC_By_P) ctx.getBean("ioC_By_P");
        ioc.checkAttr();
    }

}
  • 控制檯結果
id:1
----------------------------
name:命名空間
----------------------------
user:1|P|233
----------------------------
全部正確!!!

5、使用註解方式注入

Spring在3.0以後,提供了基於Annotation(註解)的注入。

1.@Autowired -對成員變量、方法和構造函數進行標註,來完成自動裝配的工作,不推薦使用
2.@Qualifier -配合@Autowired來解決裝配多個同類型的bean
3.@Resource -JSR-250標準註解,作用相當於@Autowired,只不過@Autowired按byType自動注入,而@Resource默認按byName自動注入
4.@PostConstruct -在方法上加上註解@PostConstruct,這個方法就會在Bean初始化之後被Spring容器執行
5.@PreDestroy -在方法上加上註解@PreDestroy,這個方法就會在Bean初始化之後被Spring容器執行
6.@Component -只需要在對應的類上加上一個@Component註解,就將該類定義爲一個Bean,不推薦使用,推薦使用更加細化的三種:@Repository、@Service、@Controller

  • @Repository 存儲層Bean
  • @Service 業務層Bean
  • @Controller 展示層Bean

7.@Scope -定義Bean的作用範圍

  • 首先配置applicationContext.xml開啓註解
    <!-- 掃描包中註解標註的類 -->
    <context:component-scan base-package="com.bc.ioc.demo05"/>
  • 實體Bean加註解
@Repository
public class User {

    private Integer id = 1;

    private String userName = "註解注入";

    private String passWord = "233";

    public User() {
        super();
    }

    public User(Integer id, String userName, String passWord) {
        super();
        this.id = id;
        this.userName = userName;
        this.passWord = passWord;
    }

    public Integer getId() {
        return id;
    }

    public String getUserName() {
        return userName;
    }

    public String getPassWord() {
        return passWord;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

}
  • 測試類代碼加註解
/**使用註解注入屬性*/
@Service("ioC_By_Annotation")
public class IoC_By_Annotation {
    @Resource
    private User user;

    public void setUser(User user) {
        this.user = user;
    }

    /**檢查是否注入成功*/
    public boolean checkAttr() {
        if(user == null) {
            return false;
        }else {
            System.out.println("user:" + user.getId() + "|" + 
                    user.getUserName() + "|" + user.getPassWord());
        }
        System.out.println("正確!!!");
        return true;
    }
}
  • 測試代碼
public class IoC_Test {

    private ApplicationContext ctx;

    @Before
    public void load() {
        //讀取applicationContext.xml配置文件
        ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    }

    @Test
    public void annotationTest() {
        IoC_By_Annotation ioc = (IoC_By_Annotation) ctx.getBean("ioC_By_Annotation");
        ioc.checkAttr();
    }

}
  • 控制檯輸出

經測試使用註解注入如果applicationContext.xml配置有其他注入方式會報錯,也會導致其他注入方式異常。

user:1|註解注入|233
正確!!!

6、通過配置靜態工廠方法Bean注入

  • 靜態工廠代碼
/**靜態工廠*/
public class StaticFactory {

    public static Integer getId() {
        return 1;
    }

    public static String getName() {
        return "靜態工廠";
    }

    public static User getUser() {
        return new User(1, "工廠User", "666");
    }
}
  • 測試類代碼
/** 通過靜態工廠方式注入 */
public class IoC_By_StaticFactory {

    private Integer id;
    private String name;
    private User user;

    /** 檢查是否注入成功 */
    public boolean checkAttr() {
        if (id == null) {
            return false;
        } else {
            System.out.println("id:" + id);
        }
        System.out.println("----------------------------");
        if (name == null) {
            return false;
        } else {
            System.out.println("name:" + name);
        }
        System.out.println("----------------------------");
        if (user == null) {
            return false;
        } else {
            System.out.println("user:" + user.getId() + "|"
                    + user.getUserName() + "|" + user.getPassWord());
        }
        System.out.println("----------------------------");
        System.out.println("全部正確!!!");
        return true;
    }

    /**需要爲需要注入的屬性設置set方法*/
    public void setId(Integer id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setUser(User user) {
        this.user = user;
    }

}
  • applicationContext.xml配置
    <!-- 配置靜態工廠方法Bean 其實就是將工廠方法返回的數值配置成Bean -->
    <bean id="factory_id" class="com.bc.ioc.demo06.StaticFactory" factory-method="getId"/>
    <bean id="factory_name" class="com.bc.ioc.demo06.StaticFactory" factory-method="getName"/>
    <bean id="factory_user" class="com.bc.ioc.demo06.StaticFactory" factory-method="getUser"/>
    <!-- 注入對應的靜態工廠方法Bean -->
    <bean id="ioC_By_StaticFactory" class="com.bc.ioc.demo06.IoC_By_StaticFactory">
        <property name="id" ref="factory_id"/>
        <property name="name" ref="factory_name"/>
        <property name="user" ref="factory_user"/>
    </bean>
  • 測試代碼
public class IoC_Test {

    private ApplicationContext ctx;

    @Before
    public void load() {
        //讀取applicationContext.xml配置文件
        ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    }

    @Test
    public void staticFactoryTest() {
        IoC_By_StaticFactory ioc = (IoC_By_StaticFactory) ctx.getBean("ioC_By_StaticFactory");
        ioc.checkAttr();
    }
}
  • 控制檯輸出結果
id:1
----------------------------
name:靜態工廠
----------------------------
user:1|工廠User|666
----------------------------
全部正確!!!

7、通過實例工廠方法注入

與靜態工廠區別在於實例工廠不是靜態的,需要先new 一個實例工廠對象,纔可以配置其方法,而new 的這個對象也由spring來管理

  • 工廠代碼
/**實例工廠*/
public class Factory {

    public Integer getId() {
        return 1;
    }

    public String getName() {
        return "實例工廠";
    }

    public User getUser() {
        return new User(1, "實例工廠User", "233");
    }
}
  • 測試類代碼
/**實例工廠注入*/
public class IoC_By_Factory {

    private Integer id;
    private String name;
    private User user;

    /** 檢查是否注入成功 */
    public boolean checkAttr() {
        if (id == null) {
            return false;
        } else {
            System.out.println("id:" + id);
        }
        System.out.println("----------------------------");
        if (name == null) {
            return false;
        } else {
            System.out.println("name:" + name);
        }
        System.out.println("----------------------------");
        if (user == null) {
            return false;
        } else {
            System.out.println("user:" + user.getId() + "|"
                    + user.getUserName() + "|" + user.getPassWord());
        }
        System.out.println("----------------------------");
        System.out.println("全部正確!!!");
        return true;
    }

    /**需要爲需要注入的屬性設置set方法*/
    public void setId(Integer id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setUser(User user) {
        this.user = user;
    }
}
  • applicationContext.xml配置
    <!-- 配置實例工廠Bean -->
    <bean id="factory" class="com.bc.ioc.demo07.Factory"/>
    <!-- 配置實例工廠方法Bean -->
    <bean id="f_id" factory-bean="factory" factory-method="getId"/>
    <bean id="f_name" factory-bean="factory" factory-method="getName"/>
    <bean id="f_user" factory-bean="factory" factory-method="getUser"/>
    <!-- 注入對應的實例工廠方法Bean -->
    <bean id="ioC_By_Factory" class="com.bc.ioc.demo07.IoC_By_Factory">
        <property name="id" ref="f_id"/>
        <property name="name" ref="f_name"/>
        <property name="user" ref="f_user"/>
    </bean>
  • 測試類代碼
public class IoC_Test {

    private ApplicationContext ctx;

    @Before
    public void load() {
        //讀取applicationContext.xml配置文件
        ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    }

    @Test
    public void factoryTest() {
        IoC_By_Factory ioc = (IoC_By_Factory) ctx.getBean("ioC_By_Factory");
        ioc.checkAttr();
    }
}
  • 控制檯輸出
id:1
----------------------------
name:實例工廠
----------------------------
user:1|實例工廠User|233
----------------------------
全部正確!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章