本节主要内容:
    1. 给MessageBean注入参数值
    2. 测试Spring自动组件扫描方式
    3. 如何控制ExampleBean实例化方式
    4. 使用注解方式重构JdbcDataSource, UserDAO, UserService

本文作者:souvc

本文出处:http://www.cnblogs.com/liuhongfeng/p/4582664.html

1 给MessageBean注入参数值

1.1 问题

Spring可以通过配置文件为bean注入多种类型的属性, MessageBean类用于演示Spring的多种类型数据的注入方式, 这些类型数据和注入方式包括:

1. 注入基本值。

2. 注入Bean对象(请参考Unit 1案例)。

3. 直接集合注入。

4. 引用方式集合注入

5. 注入Spring表达式值。

6. 注入null或空字符串。

1.2 步骤

步骤一:新建工程,导入Spring API jar包

新建名为SouvcSpringIoC_02的web工程,在该工程导入5个jar包。

 
commons-logging.jar
spring-core.jar
spring-context.jar
spring-beans.jar
spring-expression.jar
 
网盘下载jar包 :http://yunpan.cn/cQJhPMPRZeLH7  访问密码 2bf8

步骤二:新建Spring配置文件

在src目录下,新建Spring配置文件applicationContext.xml。该文件名为Spring默认的配置文件名,也可以自由定义名称。

applicationContext.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:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd"> </beans>

步骤三:新建类MessageBean 添加基本值属性

新建类MessageBean,在该类中添加如下代码中的四个属性,并生成这几个属性对应的getter和setter方法;最后在execute方法获取这几个属性的信息,代码如下所示:

package com.souvc.bean;

public class MessageBean {
private String moduleName;
private int pageSize;
private String username;
private String password = ""; public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public String getModuleName() {
return moduleName;
} public void setModuleName(String moduleName) {
this.moduleName = moduleName;
} public int getPageSize() {
return pageSize;
} public void setPageSize(int pageSize) {
this.pageSize = pageSize;
} public String execute() {
System.out.println("moduleName=" + moduleName);
System.out.println("pageSize=" + pageSize);
System.out.println("username=" + username);
System.out.println("password=" + password);
System.out.println("---List信息如下---");
return "success";
} }

步骤四:修改applicationContext.xml文件, 增加属性基本值注入

修改applicationContext.xml文件,为MessageBean的四个属性注入基本参数值,代码如图-3所示:

    <bean id="messagebean" class="com.souvc.bean.MessageBean">
<property name="moduleName" value="测试基本属性"></property>
<property name="pageSize" value="5"></property>
<property name="username" value="daliu_it"></property>
<property name="password" value="123456"></property>
</bean>

步骤五:新建类Test1, 添加测试方法获取MessageBean对象测试注入结果

新建类Test1,在类中使用ApplicationContext的方式实例化Spring容器,获取MessageBean对象,并调用execute方法。

@Test
public void test1() {
String conf = "applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
System.out.println(ac); MessageBean messagebean = ac.getBean("messagebean", MessageBean.class);
System.out.println(messagebean.toString());
messagebean.execute();
}

步骤六:运行Test1类, 测试注入结果

运行Test1类,控制台输入结果

org.springframework.context.support.ClassPathXmlApplicationContext@65b4fad5: startup date [Wed Jun 17 11:16:13 CST 2015]; root of context hierarchy
com.souvc.bean.MessageBean@5d3e754f
moduleName=测试基本属性
pageSize=5
username=daliu_it
password=123456
---List信息如下---

控制台输出所示的信息,说明获取到了注入的基本属性值。

步骤七:为MessageBean添加集合属性,用于注入集合测试

1. 修改类MessageBean,在该类中添加如下加粗代码中的四个属性,并生成这几个属性对应的getter和setter方法;最后在execute方法获取这几个属性的信息,代码如下所示:

 
  • private List<String> someList;
  • private Set<String> someSet;
  • private Map<String,Object> someMap;
  • private Properties someProps;

 
package com.souvc.bean;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set; public class MessageBean {
private String moduleName;
private int pageSize;
private String username;
private String password = ""; private List<String> someList;
private Set<String> someSet;
private Map<String,Object> someMap;
private Properties someProps; public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public String getModuleName() {
return moduleName;
} public void setModuleName(String moduleName) {
this.moduleName = moduleName;
} public int getPageSize() {
return pageSize;
} public void setPageSize(int pageSize) {
this.pageSize = pageSize;
} public List<String> getSomeList() {
return someList;
} public void setSomeList(List<String> someList) {
this.someList = someList;
} public Set<String> getSomeSet() {
return someSet;
} public void setSomeSet(Set<String> someSet) {
this.someSet = someSet;
} public Map<String, Object> getSomeMap() {
return someMap;
} public void setSomeMap(Map<String, Object> someMap) {
this.someMap = someMap;
} public Properties getSomeProps() {
return someProps;
} public void setSomeProps(Properties someProps) {
this.someProps = someProps;
} public String execute() {
System.out.println("moduleName=" + moduleName);
System.out.println("pageSize=" + pageSize);
System.out.println("username=" + username);
System.out.println("password=" + password);
System.out.println("---List信息如下---"); for(String s : someList){
System.out.println(s);
}
System.out.println("---Set信息如下---");
for(String s : someSet){
System.out.println(s);
}
System.out.println("---Map信息如下---");
Set<String> keys = someMap.keySet();
for(String key : keys){
System.out.println(key+"="
+someMap.get(key));
}
System.out.println("---Properties信息如下---");
Set<Object> keys1 = someProps.keySet();
for(Object key : keys1){
System.out.println(key+"="
+someProps.getProperty(key.toString()));
} return "success";
} }

2. 修改applicationContext.xml文件,为MessageBean的四个属性注入集合参数值:

<?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:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd"> <!-- 加载properties文件为bean
<util:properties id="jdbcProperties"
location="classpath:db.properties" /> --> <bean id="messagebean" class="com.souvc.bean.MessageBean">
<property name="moduleName" value="测试基本属性的注入"></property>
<property name="pageSize" value="5"></property>
<!-- 表达式注入 -->
<property name="username" value="daliu_it"></property>
<property name="password" value="123456"></property>
<property name="someList">
<list>
<value>北京</value>
<value>上海</value>
<value>广州</value>
</list>
</property>
<property name="someSet">
<set>
<value>James Gosling</value>
<value>Martin fowler</value>
<value>Larry Ellision</value>
</set>
</property>
<property name="someMap">
<map>
<entry key="1001" value="Java语言基础"></entry>
<entry key="1002" value="Java Web基础"></entry>
<entry key="1003" value="Spring使用基础"></entry>
</map>
</property>
<property name="someProps">
<props>
<prop key="username">root</prop>
<prop key="password">1234</prop>
</props>
</property>
</bean> <!-- 定义集合Bean
<util:list id="oneList">
<value>Tom</value>
<value>Andy</value>
</util:list>
<util:set id="oneSet">
<value>James Gosling</value>
<value>Martin fowler</value>
</util:set>
<util:map id="oneMap">
<entry key="1001" value="Java语言基础"></entry>
<entry key="1002" value="Java Web基础"></entry>
</util:map>
<util:properties id="oneProps">
<prop key="username">root</prop>
<prop key="password">1234</prop>
</util:properties> --> <!-- 引用方式注入集合属性
<bean id="messagebean2" class="com.souvc.bean.MessageBean">
<property name="moduleName" value="资费管理"></property>
<property name="pageSize" value="5"></property>
<property name="username" value="andy"></property>
<property name="password" value="123"></property>--> <!-- 引用方式注入集合属性
<property name="someList" ref="oneList" />
<property name="someSet" ref="oneSet" />
<property name="someMap" ref="oneMap" />
<property name="someProps" ref="oneProps" />
</bean>-->
</beans>

3. 运行Test1类,控制台输出结果所示:

 
org.springframework.context.support.ClassPathXmlApplicationContext@42704baa: startup date [Wed Jun 17 11:30:43 CST 2015]; root of context hierarchy
com.souvc.bean.MessageBean@25961581
moduleName=测试基本属性的注入
pageSize=5
username=daliu_it
password=123456
---List信息如下---
北京
上海
广州
---Set信息如下---
James Gosling
Martin fowler
Larry Ellision
---Map信息如下---
1001=Java语言基础
1002=Java Web基础
1003=Spring使用基础
---Properties信息如下---
password=1234
username=root

控制台输出的信息,说明只需要通过配置Spring就可以为Bean注入集合参数值。

步骤八:测试引用方式集合注入

1.为Spring配置文件applicationContext.xml增加如下配置, 采用引用方式注入集合对象, 代码参考如下:

<!-- 定义集合Bean -->
<util:list id="oneList">
<value>Tom</value>
<value>Andy</value>
</util:list>
<util:set id="oneSet">
<value>James Gosling</value>
<value>Martin fowler</value>
</util:set>
<util:map id="oneMap">
<entry key="1001" value="Java语言基础"></entry>
<entry key="1002" value="Java Web基础"></entry>
</util:map>
<util:properties id="oneProps">
<prop key="username">root</prop>
<prop key="password">1234</prop>
</util:properties> <!-- 引用方式注入集合属性 -->
<bean id="messagebean2" class="com.souvc.bean.MessageBean">
<property name="moduleName" value="资费管理"></property>
<property name="pageSize" value="5"></property>
<property name="username" value="andy"></property>
<property name="password" value="123"></property> <!-- 引用方式注入集合属性 -->
<property name="someList" ref="oneList" />
<property name="someSet" ref="oneSet" />
<property name="someMap" ref="oneMap" />
<property name="someProps" ref="oneProps" />
</bean>
 

2. 增加Test2类测试如上配置, Test2代码如下:

package com.souvc.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.souvc.bean.MessageBean; public class TestCase { @Test
public void test1() {
String conf = "applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
System.out.println(ac); MessageBean messagebean = ac.getBean("messagebean", MessageBean.class);
System.out.println(messagebean.toString());
messagebean.execute();
} @Test
public void test2() {
String conf = "applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
MessageBean bean = ac.getBean("messagebean2", MessageBean.class);
bean.execute();
}
}
 
 

3. 执行Test2 有如下结果所示:

moduleName=资费管理
pageSize=5
username=andy
password=123
---List信息如下---
Tom
Andy
---Set信息如下---
James Gosling
Martin fowler
---Map信息如下---
1001=Java语言基础
1002=Java Web基础
---Properties信息如下---
password=1234
username=root

这个结果说明, 通过引用方式也可以为bean注入集合属性.

步骤九:利用 Spring表达式注入属性值

1.在工程的src下,新建属性文件db.properties,文件内容如下:

user=scott

2. 修改applicationContext.xml文件,注入Spring表达式值,代码所示:

<!-- 加载properties文件为bean -->
<util:properties id="jdbcProperties" location="classpath:db.properties" /> <bean id="messagebean" class="org.tarena.bean.MessageBean"> <!-- ================================================================ --> <property name="moduleName" value="资费管理"></property>
<property name="pageSize" value="5"></property>
<!-- 表达式注入 -->
<property name="username" value="#{jdbcProperties.user}"></property> <property name="password">
<null />
</property>

3. 运行Test1类,控制台输出结果所示:

org.springframework.context.support.ClassPathXmlApplicationContext@68861f24: startup date [Wed Jun 17 11:41:35 CST 2015]; root of context hierarchy
com.souvc.bean.MessageBean@209444d1
moduleName=测试基本属性的注入
pageSize=5
username=daliu_it
password=123456
---List信息如下---
北京
上海
广州
---Set信息如下---
James Gosling
Martin fowler
Larry Ellision
---Map信息如下---
1001=Java语言基础
1002=Java Web基础
1003=Spring使用基础
---Properties信息如下---
password=1234
username=root

控制台输出信息,说明获取到了注入的Spring表达式值。

步骤十:注入null值

1. 修改applicationContext.xml文件,将属性password注入null值,代码如图-11所示:

<?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:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd"> <!-- 加载properties文件为bean-->
<util:properties id="jdbcProperties"
location="classpath:db.properties" /> <bean id="messagebean" class="com.souvc.bean.MessageBean">
<property name="moduleName" value="测试基本属性的注入"></property>
<property name="pageSize" value="5"></property>
<!-- 表达式注入
<property name="username" value="daliu_it"></property>-->
<property name="username" value="#{jdbcProperties.user}"></property>
<property name="password" >
<null/>
</property>
<property name="someList">
<list>
<value>北京</value>
<value>上海</value>
<value>广州</value>
</list>
</property>
<property name="someSet">
<set>
<value>James Gosling</value>
<value>Martin fowler</value>
<value>Larry Ellision</value>
</set>
</property>
<property name="someMap">
<map>
<entry key="1001" value="Java语言基础"></entry>
<entry key="1002" value="Java Web基础"></entry>
<entry key="1003" value="Spring使用基础"></entry>
</map>
</property>
<property name="someProps">
<props>
<prop key="username">root</prop>
<prop key="password">1234</prop>
</props>
</property>
</bean> <!-- 定义集合Bean -->
<util:list id="oneList">
<value>Tom</value>
<value>Andy</value>
</util:list>
<util:set id="oneSet">
<value>James Gosling</value>
<value>Martin fowler</value>
</util:set>
<util:map id="oneMap">
<entry key="1001" value="Java语言基础"></entry>
<entry key="1002" value="Java Web基础"></entry>
</util:map>
<util:properties id="oneProps">
<prop key="username">root</prop>
<prop key="password">1234</prop>
</util:properties> <!-- 引用方式注入集合属性 -->
<bean id="messagebean2" class="com.souvc.bean.MessageBean">
<property name="moduleName" value="资费管理"></property>
<property name="pageSize" value="5"></property>
<property name="username" value="andy"></property>
<property name="password" value="123"></property> <!-- 引用方式注入集合属性 -->
<property name="someList" ref="oneList" />
<property name="someSet" ref="oneSet" />
<property name="someMap" ref="oneMap" />
<property name="someProps" ref="oneProps" />
</bean>
</beans>

2. 运行Test1类,控制台输出结果:

org.springframework.context.support.ClassPathXmlApplicationContext@2996c1b0: startup date [Wed Jun 17 11:42:47 CST 2015]; root of context hierarchy
com.souvc.bean.MessageBean@195ed659
moduleName=测试基本属性的注入
pageSize=5
username=daliu_it
password=null
---List信息如下---
北京
上海
广州
---Set信息如下---
James Gosling
Martin fowler
Larry Ellision
---Map信息如下---
1001=Java语言基础
1002=Java Web基础
1003=Spring使用基础
---Properties信息如下---
password=1234
username=root

控制台输出所示的信息,说明获取到了注入的null值。

1.3 完整代码

MessageBean类的完整代码如下所示:

package com.souvc.bean;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set; public class MessageBean {
private String moduleName;
private int pageSize;
private String username;
private String password = ""; private List<String> someList;
private Set<String> someSet;
private Map<String, Object> someMap;
private Properties someProps; public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public String getModuleName() {
return moduleName;
} public void setModuleName(String moduleName) {
this.moduleName = moduleName;
} public int getPageSize() {
return pageSize;
} public void setPageSize(int pageSize) {
this.pageSize = pageSize;
} public List<String> getSomeList() {
return someList;
} public void setSomeList(List<String> someList) {
this.someList = someList;
} public Set<String> getSomeSet() {
return someSet;
} public void setSomeSet(Set<String> someSet) {
this.someSet = someSet;
} public Map<String, Object> getSomeMap() {
return someMap;
} public void setSomeMap(Map<String, Object> someMap) {
this.someMap = someMap;
} public Properties getSomeProps() {
return someProps;
} public void setSomeProps(Properties someProps) {
this.someProps = someProps;
} public String execute() {
System.out.println("moduleName=" + moduleName);
System.out.println("pageSize=" + pageSize);
System.out.println("username=" + username);
System.out.println("password=" + password);
System.out.println("---List信息如下---"); for (String s : someList) {
System.out.println(s);
}
System.out.println("---Set信息如下---");
for (String s : someSet) {
System.out.println(s);
}
System.out.println("---Map信息如下---");
Set<String> keys = someMap.keySet();
for (String key : keys) {
System.out.println(key + "=" + someMap.get(key));
}
System.out.println("---Properties信息如下---");
Set<Object> keys1 = someProps.keySet();
for (Object key : keys1) {
System.out.println(key + "="
+ someProps.getProperty(key.toString()));
} return "success";
} }

Test1,Test2的完整代码如下:

package com.souvc.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.souvc.bean.MessageBean; public class TestCase { @Test
public void test1() {
String conf = "applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
System.out.println(ac); MessageBean messagebean = ac.getBean("messagebean", MessageBean.class);
System.out.println(messagebean.toString());
messagebean.execute();
} @Test
public void test2() {
String conf = "applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
MessageBean bean = ac.getBean("messagebean2", MessageBean.class);
bean.execute();
}
}

applicationContext.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:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd"> <!-- 加载properties文件为bean-->
<util:properties id="jdbcProperties"
location="classpath:db.properties" /> <bean id="messagebean" class="com.souvc.bean.MessageBean">
<property name="moduleName" value="测试基本属性的注入"></property>
<property name="pageSize" value="5"></property>
<!-- 表达式注入
<property name="username" value="daliu_it"></property>-->
<property name="username" value="#{jdbcProperties.user}"></property>
<property name="password" >
<null/>
</property>
<property name="someList">
<list>
<value>北京</value>
<value>上海</value>
<value>广州</value>
</list>
</property>
<property name="someSet">
<set>
<value>James Gosling</value>
<value>Martin fowler</value>
<value>Larry Ellision</value>
</set>
</property>
<property name="someMap">
<map>
<entry key="1001" value="Java语言基础"></entry>
<entry key="1002" value="Java Web基础"></entry>
<entry key="1003" value="Spring使用基础"></entry>
</map>
</property>
<property name="someProps">
<props>
<prop key="username">root</prop>
<prop key="password">1234</prop>
</props>
</property>
</bean> <!-- 定义集合Bean -->
<util:list id="oneList">
<value>Tom</value>
<value>Andy</value>
</util:list>
<util:set id="oneSet">
<value>James Gosling</value>
<value>Martin fowler</value>
</util:set>
<util:map id="oneMap">
<entry key="1001" value="Java语言基础"></entry>
<entry key="1002" value="Java Web基础"></entry>
</util:map>
<util:properties id="oneProps">
<prop key="username">root</prop>
<prop key="password">1234</prop>
</util:properties> <!-- 引用方式注入集合属性 -->
<bean id="messagebean2" class="com.souvc.bean.MessageBean">
<property name="moduleName" value="资费管理"></property>
<property name="pageSize" value="5"></property>
<property name="username" value="andy"></property>
<property name="password" value="123"></property> <!-- 引用方式注入集合属性 -->
<property name="someList" ref="oneList" />
<property name="someSet" ref="oneSet" />
<property name="someMap" ref="oneMap" />
<property name="someProps" ref="oneProps" />
</bean>
</beans>

源码如下:http://yunpan.cn/cQVU3sLcMzXGC  访问密码 daf3

2 测试Spring自动组件扫描方式

2.1 问题

如何使用组件扫描的方式和"注解标记"配合获取容器中的ExampleBean对象。

2.2 方案

使用组件扫描,首先需要在XML配置中指定扫描类路径,配置代码如下:

    <context:component-scan
base-package="com.souvc"/>

上述配置,容器实例化时会自动扫描com.souvc 包及其子包下所有组件类。

指定扫描类路径后,并不是该路径下所有组件类都扫描到Spring容器的,只有在组件类定义前面有以下注解标记时,才会扫描到Spring容器。

@Component  泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。

@Name 通用注解

@Service  业务层组件注解, 用于标注业务层组件

@Repository  持久层组件注解,用于标注数据访问组件,即DAO组件

@Controller  控制层组件注解,用于标注控制层组件(如struts中的action)

2.3 步骤

步骤一:新建类ExampleBean

新建类ExampleBean,在该类前使用通用组件注解“@Component”,表明ExampleBean为可被扫描的组件,代码如下所示:

package com.souvc.bean;

import org.springframework.stereotype.Component;

@Component
public class ExampleBean { public ExampleBean() {
System.out.println("实例化ExampleBean");
} public void execute() {
System.out.println("执行ExampleBean处理");
}
}
 

步骤二: 修改applicationContext.xml

修改applicationContext.xml,使容器实例化时自动扫描org.tarena包及其子包下所有组件类

 
<!-- 组件扫描 -->
<context:component-scan base-package="com.souvc" />

步骤三: 新建方法Test3

@Test
public void test3() {
String conf = "applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
ExampleBean bean = ac.getBean("exampleBean", ExampleBean.class);
bean.execute();
}

运行Test3方法,控制台输出结果:

实例化ExampleBean
执行ExampleBean处理

控制台输出上述结果,说明Spring会自动使用组件扫描的方式创建ExampleBean实例, 并且Test3中获取到了这个ExampleBean对象。

2.4 完整代码

ExampleBean类的完整代码如下所示:

package com.souvc.bean;

import org.springframework.stereotype.Component;

@Component
public class ExampleBean { public ExampleBean() {
System.out.println("实例化ExampleBean");
} public void execute() {
System.out.println("执行ExampleBean处理");
}
}

TestCase 类的完整代码如下所示:

package com.souvc.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.souvc.bean.ExampleBean;
import com.souvc.bean.MessageBean; public class TestCase { @Test
public void test1() {
String conf = "applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
System.out.println(ac); MessageBean messagebean = ac.getBean("messagebean", MessageBean.class);
System.out.println(messagebean.toString());
messagebean.execute();
} @Test
public void test2() {
String conf = "applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
MessageBean bean = ac.getBean("messagebean2", MessageBean.class);
bean.execute();
} @Test
public void test3() {
String conf = "applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
ExampleBean bean = ac.getBean("exampleBean", ExampleBean.class);
bean.execute();
}
}

applicationContext.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:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd"> <!-- 加载properties文件为bean-->
<util:properties id="jdbcProperties"
location="classpath:db.properties" /> <bean id="messagebean" class="com.souvc.bean.MessageBean">
<property name="moduleName" value="测试基本属性的注入"></property>
<property name="pageSize" value="5"></property>
<!-- 表达式注入
<property name="username" value="daliu_it"></property>-->
<property name="username" value="#{jdbcProperties.user}"></property>
<property name="password">
<null />
</property>
<property name="someList">
<list>
<value>北京</value>
<value>上海</value>
<value>广州</value>
</list>
</property>
<property name="someSet">
<set>
<value>James Gosling</value>
<value>Martin fowler</value>
<value>Larry Ellision</value>
</set>
</property>
<property name="someMap">
<map>
<entry key="1001" value="Java语言基础"></entry>
<entry key="1002" value="Java Web基础"></entry>
<entry key="1003" value="Spring使用基础"></entry>
</map>
</property>
<property name="someProps">
<props>
<prop key="username">root</prop>
<prop key="password">1234</prop>
</props>
</property>
</bean> <!-- 定义集合Bean -->
<util:list id="oneList">
<value>Tom</value>
<value>Andy</value>
</util:list>
<util:set id="oneSet">
<value>James Gosling</value>
<value>Martin fowler</value>
</util:set>
<util:map id="oneMap">
<entry key="1001" value="Java语言基础"></entry>
<entry key="1002" value="Java Web基础"></entry>
</util:map>
<util:properties id="oneProps">
<prop key="username">root</prop>
<prop key="password">1234</prop>
</util:properties> <!-- 引用方式注入集合属性 -->
<bean id="messagebean2" class="com.souvc.bean.MessageBean">
<property name="moduleName" value="资费管理"></property>
<property name="pageSize" value="5"></property>
<property name="username" value="andy"></property>
<property name="password" value="123"></property> <!-- 引用方式注入集合属性 -->
<property name="someList" ref="oneList" />
<property name="someSet" ref="oneSet" />
<property name="someMap" ref="oneMap" />
<property name="someProps" ref="oneProps" />
</bean> <!-- 组件扫描 -->
<context:component-scan base-package="com.souvc" /> </beans>

3 如何控制ExampleBean实例化方式

3.1 问题

使用组件扫描的方式,重构如何控制ExampleBean实例化为单例或非单例模式。

3.2 方案

1. 通常受Spring管理的组件,默认的作用域是"singleton"。如果需要其他的作用域可以使用@Scope注解,只要在注解中提供作用域的名称即可,代码如下:

    @Component
@Scope("singleton")
public class ExampleBean {
...
}

2. @PostConstruct和@PreDestroy注解标记分别用于指定初始化和销毁回调方法,代码如下:

    public class ExampleBean {
@PostConstruct
public void init() {
//初始化回调方法
} @PreDestroy
public void destroy() {
//销毁回调方法
}
}

3.3 步骤

步骤一:Bean对象的创建模式

1. 修改ExampleBean,使用prototype模式创建 ExampleBean 对象,修改的代码:

package com.souvc.bean;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; @Component
@Scope("prototype")
public class ExampleBean { public ExampleBean() {
System.out.println("实例化ExampleBean");
} // public void execute() {
// System.out.println("执行ExampleBean处理");
// }
//
// @PostConstruct
// public void init() {
// System.out.println("初始化ExampleBean对象");
// }
//
// @PreDestroy
// public void destroy() {
// System.out.println("销毁ExampleBean对象");
// }
}

2. 新建类Test4在该类中创建两个ExampleBean对象,通过比较操作符==进行比较,代码如图-19所示:

    @Test
public void test4() {
String conf = "applicationContext.xml";
AbstractApplicationContext ac = new ClassPathXmlApplicationContext(conf);
ExampleBean bean1 = ac.getBean("exampleBean", ExampleBean.class);
ExampleBean bean2 = ac.getBean("exampleBean", ExampleBean.class);
System.out.println(bean1 == bean2);
ac.close();
}

3. 运行Test4,控制台输出结果如下:

实例化ExampleBean
实例化ExampleBean
false

通过前面的讲解,了解到默认情况下Spring容器是通过单例模式创建Bean对象的。通过本案例的运行结果,可以看出使用原型方式,调用了2次ExampleBean类的构造方法,说明创建了2个ExampleBean对象。

4. 如果想要使用单例模式创建对象,也可以使用注解的方式进行显示标注,修改ExampleBean类的代码所示:

package com.souvc.bean;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; @Component
//@Scope("prototype")
@Scope("singleton")
public class ExampleBean { public ExampleBean() {
System.out.println("实例化ExampleBean");
} // public void execute() {
// System.out.println("执行ExampleBean处理");
// }
//
// @PostConstruct
// public void init() {
// System.out.println("初始化ExampleBean对象");
// }
//
// @PreDestroy
// public void destroy() {
// System.out.println("销毁ExampleBean对象");
// }
}

5. 再次运行Test4,控制台输出结果如下:

实例化ExampleBean
true
 

上述运行结果可以看得出,两个ExampleBean对象,通过比较操作符“ ==”进行比较的输出结果为true,说明Spring容器是通过单例模式创建Bean对象的。

步骤二:Bean对象的初始化和销毁

1. 修改ExampleBean类,加入方法init和方法destroy,并使用注解“@PostConstruct”和注解“@PreDestroy”指定init为初始化的回调方法、destroy为销毁的回调方法,代码如下所示:

package com.souvc.bean;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; @Component
//@Scope("prototype")
@Scope("singleton")
public class ExampleBean { public ExampleBean() {
System.out.println("实例化ExampleBean");
} public void execute() {
System.out.println("执行ExampleBean处理");
} @PostConstruct
public void init() {
System.out.println("初始化ExampleBean对象");
} @PreDestroy
public void destroy() {
System.out.println("销毁ExampleBean对象");
}
}

2.运行Test4类,控制台输出结果所示:

实例化ExampleBean
初始化ExampleBean对象
true
2015-6-17 14:26:05 org.springframework.context.support.AbstractApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@45b9ce4b: startup date [Wed Jun 17 14:26:04 CST 2015]; root of context hierarchy
2015-6-17 14:26:05 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
信息: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@36f0b7f8: defining beans [jdbcProperties,messagebean,oneList,oneSet,oneMap,oneProps,messagebean2,exampleBean,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
销毁ExampleBean对象

控制台输出了“初始化ExampleBean对象”和“销毁ExampleBean对象”,说明使用组件扫描的方式为ExampleBean类添加初始化和销毁的回调方法成功。

3.4 完整代码

ExampleBean类的完整代码如下所示:

package com.souvc.bean;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; @Component
//@Scope("prototype")
@Scope("singleton")
public class ExampleBean { public ExampleBean() {
System.out.println("实例化ExampleBean");
} public void execute() {
System.out.println("执行ExampleBean处理");
} @PostConstruct
public void init() {
System.out.println("初始化ExampleBean对象");
} @PreDestroy
public void destroy() {
System.out.println("销毁ExampleBean对象");
}
}
 

Test4类的完整代码如下所示:

package com.souvc.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.souvc.bean.ExampleBean;
import com.souvc.bean.MessageBean; public class TestCase { @Test
public void test1() {
String conf = "applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
System.out.println(ac); MessageBean messagebean = ac.getBean("messagebean", MessageBean.class);
System.out.println(messagebean.toString());
messagebean.execute();
} @Test
public void test2() {
String conf = "applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
MessageBean bean = ac.getBean("messagebean2", MessageBean.class);
bean.execute();
} @Test
public void test3() {
String conf = "applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
ExampleBean bean = ac.getBean("exampleBean", ExampleBean.class);
//bean.execute();
} @Test
public void test4() {
String conf = "applicationContext.xml";
AbstractApplicationContext ac = new ClassPathXmlApplicationContext(conf);
ExampleBean bean1 = ac.getBean("exampleBean", ExampleBean.class);
ExampleBean bean2 = ac.getBean("exampleBean", ExampleBean.class);
System.out.println(bean1 == bean2);
ac.close();
} }

applicationContext.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:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd"> <!-- 加载properties文件为bean-->
<util:properties id="jdbcProperties"
location="classpath:db.properties" /> <bean id="messagebean" class="com.souvc.bean.MessageBean">
<property name="moduleName" value="测试基本属性的注入"></property>
<property name="pageSize" value="5"></property>
<!-- 表达式注入
<property name="username" value="daliu_it"></property>-->
<property name="username" value="#{jdbcProperties.user}"></property>
<property name="password">
<null />
</property>
<property name="someList">
<list>
<value>北京</value>
<value>上海</value>
<value>广州</value>
</list>
</property>
<property name="someSet">
<set>
<value>James Gosling</value>
<value>Martin fowler</value>
<value>Larry Ellision</value>
</set>
</property>
<property name="someMap">
<map>
<entry key="1001" value="Java语言基础"></entry>
<entry key="1002" value="Java Web基础"></entry>
<entry key="1003" value="Spring使用基础"></entry>
</map>
</property>
<property name="someProps">
<props>
<prop key="username">root</prop>
<prop key="password">1234</prop>
</props>
</property>
</bean> <!-- 定义集合Bean -->
<util:list id="oneList">
<value>Tom</value>
<value>Andy</value>
</util:list>
<util:set id="oneSet">
<value>James Gosling</value>
<value>Martin fowler</value>
</util:set>
<util:map id="oneMap">
<entry key="1001" value="Java语言基础"></entry>
<entry key="1002" value="Java Web基础"></entry>
</util:map>
<util:properties id="oneProps">
<prop key="username">root</prop>
<prop key="password">1234</prop>
</util:properties> <!-- 引用方式注入集合属性 -->
<bean id="messagebean2" class="com.souvc.bean.MessageBean">
<property name="moduleName" value="资费管理"></property>
<property name="pageSize" value="5"></property>
<property name="username" value="andy"></property>
<property name="password" value="123"></property> <!-- 引用方式注入集合属性 -->
<property name="someList" ref="oneList" />
<property name="someSet" ref="oneSet" />
<property name="someMap" ref="oneMap" />
<property name="someProps" ref="oneProps" />
</bean> <!-- 组件扫描 -->
<context:component-scan base-package="com.souvc" /> </beans>

本文作者:souvc

本文出处:http://www.cnblogs.com/liuhongfeng/p/4582664.html

Spring学习笔记之 Spring IOC容器(二) 之注入参数值,自动组件扫描方式,控制Bean实例化方式,使用注解方式的更多相关文章

  1. Spring学习笔记之 Spring IOC容器(一)之 实例化容器,创建JavaBean对象,控制Bean实例化,setter方式注入,依赖属性的注入,自动装配功能实现自动属性注入

    本节主要内容:       1.实例化Spring容器示例    2.利用Spring容器创建JavaBean对象    3.如何控制Bean实例化    4.利用Spring实现bean属性sett ...

  2. Spring学习(一):理解IoC容器

    序言 记得刚毕业那会儿,出来招工作被问到Spring的核心时,都觉得简单的一笔,直接说不就是IoC(控制反转)和DI(依赖注入)么,然后省略一万字对两个名词的解释.最近空来整理了一下Spring中Io ...

  3. spring学习笔记(一) Spring概述

    博主Spring学习笔记整理大部分内容来自Spring实战(第四版)这本书.  强烈建议新手购入或者需要电子书的留言. 在学习Spring之前,我们要了解这么几个问题:什么是Spring?Spring ...

  4. [Spring学习笔记 5 ] Spring AOP 详解1

    知识点回顾:一.IOC容器---DI依赖注入:setter注入(属性注入)/构造子注入/字段注入(注解 )/接口注入 out Spring IOC容器的使用: A.完全使用XML文件来配置容器所要管理 ...

  5. Java架构师之路 Spring学习笔记(一) Spring介绍

    前言 这是一篇原创的Spring学习笔记.主要记录我学习Spring4.0的过程.本人有四年的Java Web开发经验,最近在面试中遇到面试官总会问一些简单但我不会的Java问题,让我觉得有必要重新审 ...

  6. Spring学习笔记2:Spring HelloWorld

    1:IntelliJ新建Maven工程 2:pom文件加入Spring依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" ...

  7. [Spring学习笔记 1 ] Spring 简介,初步知识--Ioc容器详解 基本原理。

    一.Spring Ioc容器详解(1) 20131105 1.一切都是Bean Bean可是一个字符串或者是数字,一般是一些业务组件. 粒度一般比较粗. 2.Bean的名称 xml配置文件中,id属性 ...

  8. Spring学习笔记:Spring概述,第一个IoC依赖注入案例

    一.Spring的优点 企业及系统: 1.大规模:用户数量多.数据规模大.功能众多 2.性能和安全要求高 3.业务复杂 4.灵活应变 Java技术:高入侵式依赖EJB技术框架-->Spring框 ...

  9. Spring学习(4)IOC容器配置bean:定义与实例化

    一.  IOC容器配置 1. 一些概念 (1)IOC容器: 定义:具有管理对象和管理对象之间的依赖关系的容器. 作用:应用程序无需自己创建对象,对象由IOC容器创建并组装.BeanFactory是IO ...

随机推荐

  1. 调试报“The source file is different from when the module was built.”问题的解决

    It is related to the checksums which is used to ensure that you are stepping in matching source. You ...

  2. 野比的示波器案例(Winfrom用户控件)

    使用该用户控件做的效果图,如果数据正确,可实现 波形.直线.等等效果图...... 对于本程序的认识还是不够深彻.如果有其他方法或算法,欢迎讨论下.将我所能理解的代码都再次标识了一番. ------- ...

  3. 后缀数组---Milk Patterns

    POJ  3261 Description Farmer John has noticed that the quality of milk given by his cows varies from ...

  4. mvc设计模式和mvc框架的区别

    Spring中的新名称也太多了吧!IOC/DI/MVC/AOP/DAO/ORM... 对于刚刚接触spring的我来说确实晕了头!可是一但你完全掌握了一个概念,那么它就会死心塌地的为你服务了.这可比女 ...

  5. 使用Jsoup解析html网页

    一.   JSOUP简介 在以往用java来处理解析HTML文档或者片段时,我们通常会采用htmlparser(http://htmlparser.sourceforge.net/)这个开源类库.现在 ...

  6. .NET Core Roadmap

    This post was written by Scott Hunter. It has been about two weeks since we shipped .NET Core / ASP. ...

  7. [maven] 生命周期和插件

    maven生命周期和插件 生命周期 maven的生命周期有三套,互相独立.每个生命周期含有不同阶段,常用如下 clean 清理项目 pre-clean 执行清理前需要完成的工作 clean 清理上一次 ...

  8. viewport的一些事

    整理了下viewport的东西,用脑图画了下

  9. 人人都应该学习Markdown

    Markdown是一门新兴的标记语言,已经有12年历史了.随着它在全球范围内的流行,很多人已经听说.熟识或者开始使用了. 首先,Markdown既不是工具,也不是程序语言,而是一种十分轻量级的标记语言 ...

  10. Get a developer license for windows store app

     获取你的开发者许可证 开发人员许可证是免费.如果您通过使用微软账户获取一个或多个开发人员的许可证,您必须续订他们每隔 30 天 当您运行或调试应用程序第一次在远程机器上或直接连接到您的开发计算机的设 ...