本节主要内容:
    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. C#开源资源项目

    一.AOP框架 Encase 是C#编写开发的为.NET平台提供的AOP框架.Encase 独特的提供了把方面(aspects)部署到运行时代码,而其它AOP框架依赖配置文件的方式.这种部署方面(as ...

  2. .net C# 对虚拟目录IIS的操作

    一.查看虚拟目录是否存在 private bool IsExitesVirtualDir(string virtualdirname) {    bool exited =false;    Dire ...

  3. DevExpress GridControl功能总结

    写在前面,Dev控件已经很久了,功能也很强大,截止到现在我编写文档出来的Dev的版本已经到了14.1了,看了Demo真的很强大,效果也很好,结合自己这一个月开发,分享一下自己研究过后的经验,不让大家走 ...

  4. mysql学习笔记 第七天

    数据库的备份与还原 数据库的备份与还原是后面章节的内容,但是在学习的时候已经需要数据的备份与还原了,所以就了解了一下.数据库有很多种备份方法,我学习的是其中的一种 备份: 对于数据库的备份: C:&g ...

  5. ajax onblur 用法

    value为当前框中的值 <input  name="num"type="text"  onblur="changeorder(id,this. ...

  6. python 学习之电脑的发展历史

    电脑的发展历史 电脑的学名叫计算机,电脑是用来做计算的.在古时候,人们最早使用的计算工具可能是手指,英文单词“digit”既有“数字”的意思,又有“手指“的意思.古人用石头打猎,所以还有可能是石头来辅 ...

  7. Java中的继承

    我们在以前的学习中,我们会了C#中的继承,今天我们来了解了解Java中的继承,其实都大同小异啦! 1.语法 修饰符 SubClass extends SuperClass(){ //类定义部分 } e ...

  8. DOM笔记整理及应用实例

    一.前言 当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model).HTML DOM 模型被构造为对象的树 通过可编程的对象模型,JavaScript 获得了足够的 ...

  9. windows临界区

    临界区: 临界区是一种轻量级机制,在某一时间内只允许一个线程执行某个给定代码段.通常在多线程修改全局数据时会使用临界区.事件.信号量也用于多线程同步,但临界区与它们不同,并不总是执行向内核模式的切换, ...

  10. java微信开发(wechat4j)——设置响应微信参数

    设置响应微信参数 wechat4j框架官方文档: https://github.com/sword-org/wechat4j/wiki