Spring管理Bean-IOC 1.Spring配置/管理bean介紹 Bean管理包括兩方面: 創建bean對象 給bean註入屬性 Bean的配置方式: 基於xml文件配置方式 基於註解配置方式 2.基於XML配置bean 2.1通過類型來獲取bean 通過id來獲取bean在Spring基本 ...
Spring管理Bean-IOC
1.Spring配置/管理bean介紹
- Bean管理包括兩方面:
- 創建bean對象
- 給bean註入屬性
- Bean的配置方式:
- 基於xml文件配置方式
- 基於註解配置方式
2.基於XML配置bean
2.1通過類型來獲取bean
通過id來獲取bean在Spring基本介紹中已經使用過,這裡不再贅敘
2.1.1應用案例
-
案例說明:
- 通過spring的ioc容器,獲取一個bean對象
- 說明:獲取bean的方式:按類型
-
完成步驟:
- 創建一個Java對象Monster.java
- 在beans.xml中配置
Monster.java:
package com.li.bean;
/**
* @author 李
* @version 1.0
* Javabean / Entity
*/
public class Monster {
private Integer monsterId;
private String name;
private String skill;
//無參構造器一定要有,spring底層反射創建對象時需要使用
public Monster() {
}
public Monster(Integer monsterId, String name, String skill) {
this.monsterId = monsterId;
this.name = name;
this.skill = skill;
}
public Integer getMonsterId() {
return monsterId;
}
public void setMonsterId(Integer monsterId) {
this.monsterId = monsterId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSkill() {
return skill;
}
public void setSkill(String skill) {
this.skill = skill;
}
@Override
public String toString() {
return "Monster{" +
"monsterId=" + monsterId +
", name='" + name + '\'' +
", skill='" + skill + '\'' +
'}';
}
}
beans.xml:
<!--配置Monster,希望通過類型來獲取-->
<bean class="com.li.bean.Monster" >
<property name="monsterId" value="10086"/>
<property name="name" value="孫悟空"/>
<property name="skill" value="筋斗雲"/>
</bean>
SpringBeanTest:
package com.li.test;
import com.li.bean.Monster;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.testng.annotations.Test;
/**
* @author 李
* @version 1.0
*/
public class SpringBeanTest {
//通過Bean的類型來獲取對象
@Test
public void getBeanByType() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
//直接傳入class對象/類型
Monster bean = ioc.getBean(Monster.class);
System.out.println(bean);
}
}
2.1.2細節說明
-
按照類型來獲取bean,要求ioc容器中的同一個類的bean只能有一個,否則會拋出異常NoUniqueBeanDefinitionException
-
用類型來獲取bean的應用場景:XxxAction/Servlet/Controller或者XxxService,在一個線程中只需要一個對象實例的情況(單例情況)
-
在容器配置文件(比如beans.xml)中給屬性值,底層是通過setter方法完成的,這也是為什麼需要在java對象中提供setter方法,否則會報錯
2.2通過構造器配置bean
2.2.1應用實例
-
案例說明:
使用spring的ioc容器,可以通過構造器來來配置bean對象
-
完整步驟:
- 配置bean.xml
在beans.xml配置:
前提是Monster類中有對應的構造器
<!--配置Monster對象,並指定構造器-->
<!--
1. constructor-arg 標簽可以指定使用構造器的參數
2. index 表示構造器的第幾個參數,從0開始計算
3. 除了通過index,還可以通過 name/ type 的方式來指定參數
4. 類構造器可以有多個,但是不能有參數完全相同的類型和順序的構造器,
這就決定了 通過構造器參數type 可以唯一確定一個構造器)
-->
<bean id="monster03" class="com.li.bean.Monster">
<constructor-arg value="200" index="0"/>
<constructor-arg value="白骨精" index="1"/>
<constructor-arg value="吸血" index="2"/>
</bean>
<!--通過 name 的方式來指定參數-->
<bean id="monster04" class="com.li.bean.Monster">
<constructor-arg value="200" name="monsterId"/>
<constructor-arg value="白骨精" name="name"/>
<constructor-arg value="吸血" name="skill"/>
</bean>
<!--通過 type 的方式來指定參數-->
<bean id="monster05" class="com.li.bean.Monster">
<constructor-arg value="200" type="java.lang.Integer"/>
<constructor-arg value="白骨精" type="java.lang.String"/>
<constructor-arg value="吸血" type="java.lang.String"/>
</bean>
SpringBeanTest:
package com.li.test;
import com.li.bean.Monster;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.testng.annotations.Test;
import java.io.File;
/**
* @author 李
* @version 1.0
*/
public class SpringBeanTest {
//通過構造器來設置屬性
@Test
public void setBeanConstructor() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
Monster monster03 = ioc.getBean("monster03", Monster.class);
System.out.println("monster03=" + monster03);
}
}
2.2.2細節說明
- 通過index屬性來區分是第幾個參數
- 通過type屬性來區分是什麼類型(按照順序)
2.3通過p名稱空間配置bean
2.3.1應用實例
-
案例說明:
在spring的ioc容器,可以通過p名稱空間來配置bean對象
-
完成步驟:
- 在beans.xml配置,增加命名空間配置,如下,點擊Create namespace declaration,成功後在配置文件頭會自動添加xmlns
beans.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" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--通過p名稱空間來配置bean
將游標放在p,輸入alt+enter,就會自動添加 xmlns
-->
<bean id="monster06" class="com.li.bean.Monster"
p:monsterId="500"
p:name="紅孩兒"
p:skill="風火輪"
/>
</beans>
SpringBeanTest:
package com.li.test;
import com.li.bean.Monster;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.testng.annotations.Test;
/**
* @author 李
* @version 1.0
*/
public class SpringBeanTest {
//通過p名稱空間來設置屬性
@Test
public void setBeanByP() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
Monster monster06 = ioc.getBean("monster06", Monster.class);
System.out.println("monster06=" + monster06);
}
}
2.3.2細節說明
註意要引入p名稱空間
2.4引用/註入其他bean對象
2.4.1應用實例
-
案例說明:
在spring的ioc容器中,可以通過 ref (reference)來實現bean對象的相互應用
-
完成步驟:
- 創建MemberDAOImpl.java,MemberServiceImpl.java
- 配置beans.xml
beans.xml:
<!--配置MemberDAOImpl對象-->
<bean class="com.li.dao.MemberDAOImpl" id="memberDAO"/>
<!--配置MemberServiceImpl對象
1.ref="memberDAO" 表示
MemberServiceImpl 對象的屬性memberDAO 引用的對象是id=memberDAO的對象
2.這就體現了spring容器的依賴註入
3.註意在spring容器中,是作為一個整體來執行的,也就是說如果你引用到了一個bean對象,對你配置的順序沒有要求
(在底層,對spring配置文件進行掃描,將關聯的關係自動梳理,並放到beanDefinitionMap中,
也就是說,是從beanDefinitionMap中查找關聯關係的。與spring配置文件的配置順序無關)
4.但是建議按照順序配置,易於閱讀
-->
<bean class="com.li.service.MemberServiceImpl" id="memberService">
<property name="memberDAO" ref="memberDAO"/>
</bean>
MemberDAOImpl:
package com.li.dao;
/**
* @author 李
* @version 1.0
* DAO 對象
*/
public class MemberDAOImpl {
//構造器
public MemberDAOImpl() {
System.out.println("MemberDAOImpl 構造器...");
}
//方法
public void add() {
System.out.println("MemberDAOImpl add()方法被執行");
}
}
MemberServiceImpl:
package com.li.service;
import com.li.dao.MemberDAOImpl;
/**
* @author 李
* @version 1.0
* Service類
*/
public class MemberServiceImpl {
private MemberDAOImpl memberDAO;
public MemberDAOImpl getMemberDAO() {
return memberDAO;
}
public void setMemberDAO(MemberDAOImpl memberDAO) {
this.memberDAO = memberDAO;
}
public void add() {
System.out.println("MemberServiceImpl add() 方法被調用...");
memberDAO.add();
}
}
SpringBeanTest:
package com.li.test;
import com.li.service.MemberServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.testng.annotations.Test;
/**
* @author 李
* @version 1.0
*/
public class SpringBeanTest {
//通過ref 來設置 bean屬性
@Test
public void setBeanByRef() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
MemberServiceImpl memberService =
ioc.getBean("memberService", MemberServiceImpl.class);
memberService.add();
}
}
2.4.2細節說明
註意:在spring容器中,是作為一個整體來執行的,也就是說如果你引用到了一個bean對象,對你配置的順序沒有要求。例如這裡的例子,如果我們將Memb erDAOImpl對象的配置,放到MemberServiceImpl對象的配置之後也是可以的。
因為在底層,會對spring的配置文件進行掃描,將關聯的關係自動梳理,並放到beanDefinitionMap中。
也就是說,是從beanDefinitionMap中查找關聯關係的。與spring配置文件的配置順序無關。
但是建議按照順序配置,易於閱讀
2.5引入/註入內部bean對象
2.5.1應用實例
-
案例說明:
在spring的ioc容器中,可以直接配置內部bean對象
-
完成步驟:
- 創建MemberDAOImpl.java,MemberServiceImpl.java
- 配置beans.xml
創建MemberDAOImpl.java,MemberServiceImpl.java(見2.4)
beans.xml:
<!--配置MemberService對象(使用內部bean)-->
<bean class="com.li.service.MemberServiceImpl" id="memberService2">
<!--自己配置一個內部bean-->
<property name="memberDAO">
<bean class="com.li.dao.MemberDAOImpl"/>
</property>
</bean>
SpringBeanTest:
package com.li.test;
import com.li.service.MemberServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.testng.annotations.Test;
/**
* @author 李
* @version 1.0
*/
public class SpringBeanTest {
//通過內部 bean來設置 bean屬性
@Test
public void setBeanByProper() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
MemberServiceImpl memberService2 =
ioc.getBean("memberService2", MemberServiceImpl.class);
memberService2.add();
}
}
2.6引用/註入集合/數組類型
2.6.1應用實例
-
案例說明
在spring的ioc容器中,看看如何給bean對象的集合/數組類型屬性賦值
-
完成步驟:
- 創建Monster.java
- 創建Master.java
- 配置beans.xml
Monster.java:見2.1
Master.java:
package com.li.bean;
import java.util.*;
/**
* @author 李
* @version 1.0
* Master類
*/
public class Master {
private String name;
private List<Monster> monsterList;
private Map<String, Monster> monsterMap;
private Set<Monster> monsterSet;
//數組
private String[] monsterName;
// Properties 是 Hashtable 的子類,也是k-v形式
// 這裡Properties 的key和value都是String類型
private Properties pros;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Monster> getMonsterList() {
return monsterList;
}
public void setMonsterList(List<Monster> monsterList) {
this.monsterList = monsterList;
}
public Map<String, Monster> getMonsterMap() {
return monsterMap;
}
public void setMonsterMap(Map<String, Monster> monsterMap) {
this.monsterMap = monsterMap;
}
public Set<Monster> getMonsterSet() {
return monsterSet;
}
public void setMonsterSet(Set<Monster> monsterSet) {
this.monsterSet = monsterSet;
}
public String[] getMonsterName() {
return monsterName;
}
public void setMonsterName(String[] monsterName) {
this.monsterName = monsterName;
}
public Properties getPros() {
return pros;
}
public void setPros(Properties pros) {
this.pros = pros;
}
@Override
public String toString() {
return "Master{" +
"name='" + name + '\'' +
", monsterList=" + monsterList +
", monsterMap=" + monsterMap +
", monsterSet=" + monsterSet +
", monsterName=" + Arrays.toString(monsterName) +
", pros=" + pros +
'}';
}
}
beans.xml:
<!--配置Master對象-->
<!--體會Spring容器配置特點-->
<bean class="com.li.bean.Master" id="master">
<property name="name" value="太上老君"/>
<!--(1)給list屬性賦值-->
<property name="monsterList">
<list>
<!--方式1.引用的方式-->
<ref bean="monster01"/>
<ref bean="monster02"/>
<!--方式2.內部bean-->
<bean class="com.li.bean.Monster">
<property name="name" value="黃袍怪"/>
<property name="monsterId" value="1024"/>
<property name="skill" value="吃人"/>
</bean>
</list>
</property>
<!--(2)給map屬性賦值-->
<property name="monsterMap">
<map>
<entry>
<key>
<value>monster01</value>
</key>
<!--也可以通過內部 bean來配置,這裡使用引用-->
<ref bean="monster01"/>
</entry>
<entry>
<key>
<value>monster02</value>
</key>
<!--也可以通過內部 bean來配置,這裡使用引用-->
<ref bean="monster02"/>
</entry>
</map>
</property>
<!--(3)給set屬性賦值-->
<property name="monsterSet">
<set>
<!--同理,依然可以使用ref或者內部 bean的方式配置-->
<ref bean="monster05"/>
<bean class="com.li.bean.Monster">
<property name="name" value="金角大王"/>
<property name="monsterId" value="888"/>
<property name="skill" value="有錢"/>
</bean>
</set>
</property>
<!--(4)給數組屬性賦值-->
<property name="monsterName">
<array>
<!--這裡根據數組的類型來選擇對應的標簽-->
<value>小豬妖</value>
<value>大鵬妖</value>
<value>老狐狸</value>
<!--同理,依然可以使用ref或者內部 bean的方式配置-->
</array>
</property>
<!--(5)給Properties屬性賦值,結構 k(String)-v(String)-->
<property name="pros">
<props>
<prop key="username">root</prop>
<prop key="pwd">1234</prop>
<prop key="ip">127.0.0.1</prop>
</props>
</property>
</bean>
SpringBeanTest:
package com.li.test;
import com.li.bean.Master;
import com.li.bean.Monster;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.testng.annotations.Test;
import java.util.Iterator;
import java.util.Map;
/**
* @author 李
* @version 1.0
*/
public class SpringBeanTest {
//給集合/數組屬性進行配置值
@Test
public void setBeanByCollection() {
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
Master master = ioc.getBean("master", Master.class);
System.out.println("========master的list屬性=========");
for (Monster monster : master.getMonsterList()) {
System.out.println(monster);
}
System.out.println("\n========master的map屬性=========");
Iterator<Map.Entry<String, Monster>> iterator =
master.getMonsterMap().entrySet().iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
System.out.println("\n========master的set屬性=========");
for (Monster monster : master.getMonsterSet()) {
System.out.println(monster);
}
System.out.println("\n========master的數組屬性=========");
for (int i = 0; i < master.getMonsterName().length; i++) {
System.out.println(master.getMonsterName()[i]);
}
System.out.println("\n========master的Properties屬性=========");
Iterator<Map.Entry<Object, Object>> iterator1
= master.getPros().entrySet().iterator();
while (iterator1.hasNext()) {
System.out.println(iterator1.next());
}
}
}
2.6.2細節說明
-
主要掌握List/Map/Properties三種集合的使用
-
Properties集合的特點:
(1)Properties是Hashtable的子類,也是key-value形式
(2)key是String類型,value也是String類型