给MessageBean注入参数值
测试Spring自动组件扫描方式
如何控制ExampleBean实例化方式
使用注解方式重构JdbcDataSource, UserDAO, UserService
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.
applicationContext.
<? ="http://www.w3.org/2001/ ="http://www.springframework.org/schema/context" ="http://www.springframework.org/schema/jdbc" ="http://www.springframework.org/schema/jee" ="http://www.springframework.org/schema/tx" ="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.
修改applicationContext.
<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.; ApplicationContext ac = new ClassPath= ac.getBean("messagebean", MessageBean.class); System.out.println(messagebean.toString()); messagebean.execute(); }
步骤六:运行Test1类, 测试注入结果
运行Test1类,控制台输入结果
org.springframework.context.support.ClassPath]; root of context hierarchycom.souvc.bean.MessageBean@5d3e754fmoduleName=测试基本属性pageSize=5username=daliu_itpassword=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.
<? ="http://www.w3.org/2001/ ="http://www.springframework.org/schema/context" ="http://www.springframework.org/schema/jdbc" ="http://www.springframework.org/schema/jee" ="http://www.springframework.org/schema/tx" ="http://www.springframework.org/schema/data/jpa" ="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.ClassPath]; root of context hierarchycom.souvc.bean.MessageBean@25961581moduleName=测试基本属性的注入pageSize=5username=daliu_itpassword=123456---List信息如下---北京上海广州---Set信息如下---James GoslingMartin fowlerLarry Ellision---Map信息如下---1001=Java语言基础1002=Java Web基础1003=Spring使用基础---Properties信息如下---password=1234username=root
控制台输出的信息,说明只需要通过配置Spring就可以为Bean注入集合参数值。
步骤八:测试引用方式集合注入
1.为Spring配置文件applicationContext.
<!-- 定义集合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.ClassPathimport com.souvc.bean.MessageBean;public class TestCase { @Test public void test1() { String conf = "applicationContext.; ApplicationContext ac = new ClassPath= ac.getBean("messagebean", MessageBean.class); System.out.println(messagebean.toString()); messagebean.execute(); } @Test public void test2() { String conf = "applicationContext.; ApplicationContext ac = new ClassPath= ac.getBean("messagebean2", MessageBean.class); bean.execute(); }}
3. 执行Test2 有如下结果所示:
moduleName=资费管理pageSize=5username=andypassword=123---List信息如下---TomAndy---Set信息如下---James GoslingMartin fowler---Map信息如下---1001=Java语言基础1002=Java Web基础---Properties信息如下---password=1234username=root
这个结果说明, 通过引用方式也可以为bean注入集合属性.
步骤九:利用 Spring表达式注入属性值
1.在工程的src下,新建属性文件db.properties,文件内容如下:
user=scott
2. 修改applicationContext.
<!-- 加载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.ClassPath]; root of context hierarchycom.souvc.bean.MessageBean@209444d1moduleName=测试基本属性的注入pageSize=5username=daliu_itpassword=123456---List信息如下---北京上海广州---Set信息如下---James GoslingMartin fowlerLarry Ellision---Map信息如下---1001=Java语言基础1002=Java Web基础1003=Spring使用基础---Properties信息如下---password=1234username=root
控制台输出信息,说明获取到了注入的Spring表达式值。
步骤十:注入null值
1. 修改applicationContext.
<? ="http://www.w3.org/2001/ ="http://www.springframework.org/schema/context" ="http://www.springframework.org/schema/jdbc" ="http://www.springframework.org/schema/jee" ="http://www.springframework.org/schema/tx" ="http://www.springframework.org/schema/data/jpa" ="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.ClassPath]; root of context hierarchycom.souvc.bean.MessageBean@195ed659moduleName=测试基本属性的注入pageSize=5username=daliu_itpassword=null---List信息如下---北京上海广州---Set信息如下---James GoslingMartin fowlerLarry Ellision---Map信息如下---1001=Java语言基础1002=Java Web基础1003=Spring使用基础---Properties信息如下---password=1234username=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.ClassPathimport com.souvc.bean.MessageBean;public class TestCase { @Test public void test1() { String conf = "applicationContext.; ApplicationContext ac = new ClassPath= ac.getBean("messagebean", MessageBean.class); System.out.println(messagebean.toString()); messagebean.execute(); } @Test public void test2() { String conf = "applicationContext.; ApplicationContext ac = new ClassPath= ac.getBean("messagebean2", MessageBean.class); bean.execute(); }}
applicationContext.
<? ="http://www.w3.org/2001/ ="http://www.springframework.org/schema/context" ="http://www.springframework.org/schema/jdbc" ="http://www.springframework.org/schema/jee" ="http://www.springframework.org/schema/tx" ="http://www.springframework.org/schema/data/jpa" ="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 方案
使用组件扫描,首先需要在
<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;@Componentpublic class ExampleBean { public ExampleBean() { System.out.println("实例化ExampleBean"); } public void execute() { System.out.println("执行ExampleBean处理"); }}
步骤二: 修改applicationContext.
修改applicationContext.
<!-- 组件扫描 --> <context:component-scan base-package="com.souvc" />
步骤三: 新建方法Test3
@Test public void test3() { String conf = "applicationContext.; ApplicationContext ac = new ClassPath= 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;@Componentpublic 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.ClassPathimport com.souvc.bean.ExampleBean;import com.souvc.bean.MessageBean;public class TestCase { @Test public void test1() { String conf = "applicationContext.; ApplicationContext ac = new ClassPath= ac.getBean("messagebean", MessageBean.class); System.out.println(messagebean.toString()); messagebean.execute(); } @Test public void test2() { String conf = "applicationContext.; ApplicationContext ac = new ClassPath= ac.getBean("messagebean2", MessageBean.class); bean.execute(); } @Test public void test3() { String conf = "applicationContext.; ApplicationContext ac = new ClassPath= ac.getBean("exampleBean", ExampleBean.class); bean.execute(); }}
applicationContext.
<? ="http://www.w3.org/2001/ ="http://www.springframework.org/schema/context" ="http://www.springframework.org/schema/jdbc" ="http://www.springframework.org/schema/jee" ="http://www.springframework.org/schema/tx" ="http://www.springframework.org/schema/data/jpa" ="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.; AbstractApplicationContext ac = new ClassPath= ac.getBean("exampleBean", ExampleBean.class); ExampleBean bean2 = ac.getBean("exampleBean", ExampleBean.class); System.out.println(bean1 == bean2); ac.close(); }
3. 运行Test4,控制台输出结果如下:
实例化ExampleBean实例化ExampleBeanfalse
通过前面的讲解,了解到默认情况下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,控制台输出结果如下:
实例化ExampleBeantrue
上述运行结果可以看得出,两个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对象true2015-6-17 14:26:05 org.springframework.context.support.AbstractApplicationContext doClose信息: Closing org.springframework.context.support.ClassPath17 14:26:04 CST 2015]; root of context hierarchy2015-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.ClassPathimport com.souvc.bean.ExampleBean;import com.souvc.bean.MessageBean;public class TestCase { @Test public void test1() { String conf = "applicationContext.; ApplicationContext ac = new ClassPath= ac.getBean("messagebean", MessageBean.class); System.out.println(messagebean.toString()); messagebean.execute(); } @Test public void test2() { String conf = "applicationContext.; ApplicationContext ac = new ClassPath= ac.getBean("messagebean2", MessageBean.class); bean.execute(); } @Test public void test3() { String conf = "applicationContext.; ApplicationContext ac = new ClassPath= ac.getBean("exampleBean", ExampleBean.class); //bean.execute(); } @Test public void test4() { String conf = "applicationContext.; AbstractApplicationContext ac = new ClassPath= ac.getBean("exampleBean", ExampleBean.class); ExampleBean bean2 = ac.getBean("exampleBean", ExampleBean.class); System.out.println(bean1 == bean2); ac.close(); }}
applicationContext.
<? ="http://www.w3.org/2001/ ="http://www.springframework.org/schema/context" ="http://www.springframework.org/schema/jdbc" ="http://www.springframework.org/schema/jee" ="http://www.springframework.org/schema/tx" ="http://www.springframework.org/schema/data/jpa" ="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>
原标题:Spring学习笔记之 Spring IOC容器(二)
关键词:Spring