自学了Spring也有一段时间了,多多少少掌握了一些Spring的知识,现在手上也没有很多的项目练手,就将就着把这些学到的东西先收集起来,方便日后用到的时候没地方找。
1、spring的国际化
主要是配置文件:
1 <bean id="messageSource" 2 class="org.springframework.context.support.ResourceBundleMessageSource"> 3 4 <!-- 传入资源文件 --> 5 <!-- 类中的方法加载资源文件 setBasenames (String[] basenames) --> 6 <!-- 该方法的参数为数组 利用list --> 7 <property name="basenames"> 8 <list> 9 <value>mess</value> 10 </list> 11 </property> 12 </bean>
获取国际化信息:
System.out.println(cfx.getMessage("hello", new String[]{"chentao"},Locale.US));//第一个参数为key,第二个参数表示占位符,第三个参数表示Locale 两个国际化资源文件
mess_en_US.properties
hello={0} hello,you are welcome loginTitle={0},congratulations,{1}
mess_zh_CN.properties
hello={0} u6B22u8FCEu60A8 loginTitle={0},u606Du559Cu60A8,{1}
2、spring资源访问
1 //加载资源功能 2 Resource r = cfx.getResource("classpath:ct.txt");//从类加载路径 3 4 BufferedReader br = new BufferedReader(new InputStreamReader(r.getInputStream())); 5 String line = null; 6 while((line = br.readLine())!=null){ 7 System.out.println(line); 8 }
3、spring命名空间
配置文件的头部添加:
xmlns:p="http://www.springframework.org/schema/p"
4、spring嵌套Bean、依赖注入集合:
1 <bean id="person" class="com.csu.spring.domain.Person"> 2 <!-- 嵌套bean --> 3 <property name="userDao"> 4 <bean class="com.csu.spring.dao.UserDaoHibernate"/> 5 </property> 6 7 <property name="schools"> 8 <list> 9 <value>小学</value> <!-- String为标量类型,用value表示 --> 10 <value>中学</value> 11 <value>大学</value> 12 </list> 13 </property> 14 15 <property name="scores"> 16 <map> 17 <entry key="数学" value="98.9" /> 18 <entry key="语文" value="88" /> 19 </map> 20 </property> 21 22 <property name="health"> 23 <props> 24 <prop key="姓名">**</prop> 25 <prop key="年龄">20</prop> 26 </props> 27 </property> 28 29 30 <property name="items"> 31 <set> 32 <value>我的电脑</value> 33 <list> 34 <value>笔记本</value> 35 </list> 36 </set> 37 </property> 38 39 </bean>
5、利用静态工厂方法和实例工厂方法实例化Bean对象:
配置文件
1 <!-- 利用静态工厂方法实例化Bean对象 --> 2 <!-- 3 当设置了factory-method属性之后, 4 userService_2 = com.csu.spring.service.UserServiceFactory.createUserService() 5 --> 6 <bean id="userService_2" 7 class="com.csu.spring.service.UserServiceFactory" 8 factory-method="createUserService"> 9 <!-- 如果工厂方法有参数,通过constructor-arg元素传入 --> 10 <constructor-arg value="陈涛"/> 11 </bean> 12 13 <!-- 实例工厂方法 --> 14 <bean id="userServiceFactory" class="com.csu.spring.service.UserServiceFactory"/> 15 <bean id="userService_3" factory-bean="userServiceFactory" factory-method="createUserService_2"/>
工厂类:
1 public class UserServiceFactory { 2 3 //利用静态工厂方式实例化Bean,,以前在配置文件中都是调用Bean实现类的构造器 4 5 //假定有参数 6 public static UserService createUserService(String name){ 7 System.out.println("参数值为:" +name +"*********静态工厂方法*************"); 8 return new UserService(); 9 } 10 11 public UserService createUserService_2(){ 12 System.out.println("*********实例工厂方法*************"); 13 return new UserService(); 14 } 15 16 }
6、抽象Bean:
1 <!-- 因为模板只是一些通用的信息,所以告诉Sring不要创建Bean模板的实例, 2 增加abstract="true" --> 3 <bean id="template" abstract="true"> 4 <property name="school" value="csu"></property> 5 </bean>
<bean id="person" class="com.csu.spring.doamin.Person" parent="template"...(略)...>
7、协调作用域不同的Bean
先简单介绍一下Bean的生命周期:
Bean有4个作用域:Singleton Prototype Request Session
当Singleton的Bean依赖Prototype的Bean,由于Singleton只有一次初始化机会,这样就会导致Singleton的Bean永远依赖于最开始的注入的Prototype的Bean
解决办法:
(1)放弃依赖注入:
自定义一个方法,即Spring容器在获取singleton Bean时,都重新从Spring容器中获取一个Prototype Bean, 那么该方法要首先获取Spring容器,再获取并返回Prototype Bean:
singleton Bean要实现ApplicationContextAware接口:
1 import org.springframework.beans.BeansException; 2 import org.springframework.context.ApplicationContext; 3 import org.springframework.context.ApplicationContextAware; 4 5 public class Person implements ApplicationContextAware{ 6 7 private ApplicationContext cxt; 8 9 10 private Cat cat; 11 12 13 public void setCat(Cat cat) { 14 this.cat = cat; 15 } 16 17 18 //解决bean作用域不同步的问题 19 public Cat createCat(){ 20 //调用Spring容器重新获取prototype的Bean 21 return (Cat) cxt.getBean("cat"); 22 } 23 24 public void getcat(){ 25 System.out.println("得到猫的种类: "+createCat()); 26 } 27 28 //该方法由Spring调用,而且Spring把自身作为参数传入 29 @Override 30 public void setApplicationContext(ApplicationContext arg0) throws BeansException { 31 // TODO Auto-generated method stub 32 this.cxt = arg0; 33 } 34 35 }
(2)使用Lookup注入:
1 public abstract class Person { 2 3 4 private Fish fish; 5 6 7 public void setFish(Fish fish) { 8 this.fish = fish; 9 } 10 11 12 public abstract Fish createFish(); 13 14 15 public void getFish(){ 16 System.out.println("得到鱼的种类:" + createFish()); 17 } 18 19 20 }
1 <bean id="fish" class="com.csu.spring.doamin.Fish" scope="prototype"/> 2 3 <bean id="person" class="com.csu.spring.doamin.Person" parent="template"> 4 5 <lookup-method name = "createFish" bean="fish"/> 6 7 </bean>
lookup-method元素告诉Spring,需要先创建Person的子类,而且该子类要实现name指定的方法,这样每次在调用Person Bean的时候,都会得到新的Fish Bean.
8、FactoryBean:
FactoryBean接口是工厂Bean的标准接口,实现该接口的Bean通常作为工厂Bean使用,当我们把工厂Bean部署在容器中,并通过getBean方法来获取时,容器不会返回FactoryBean实例,
而是返回FactoryBean产品。
1 import org.springframework.beans.factory.FactoryBean; 2 3 //用于返回指定类,指定静态field的值 4 public class GetFieldFactoryBean implements FactoryBean { 5 6 private String field; 7 private String targetClass; 8 9 10 public void setField(String field) { 11 this.field = field; 12 13 } 14 15 16 17 public void setTargetClass(String targetClass) { 18 this.targetClass = targetClass; 19 20 21 } 22 23 24 25 //获取返回值 26 @Override 27 public Object getObject() throws Exception { 28 // TODO Auto-generated method stub 29 //return "hello world "; 30 Class clazz = Class.forName(targetClass); 31 32 //返回clazz类的field的值 33 return clazz.getField(field).get(clazz); 34 } 35 36 //判断返回值的类型 37 @Override 38 public Class getObjectType() { 39 // TODO Auto-generated method stub 40 return null; 41 } 42 43 //判断是否是单例 44 @Override 45 public boolean isSingleton() { 46 // TODO Auto-generated method stub 47 return false; 48 } 49 }
1 <!-- 2 如果GetFieldFactoryBean实现了FactoryBean接口。 3 那么下面的代码等于: 4 创建实例后, 5 getFieldFactoryBean = com.csu.spring.util.GetFieldFactoryBean.getObject() 6 --> 7 <bean id="getFieldFactoryBean" class="com.csu.spring.util.GetFieldFactoryBean" 8 p:field="out" p:targetClass="java.lang.System"> 9 </bean>
9、Spring调用get方法
1 <?xml version="1.0" encoding="UTF-8"?> 2 3 <!-- 整个Spring 文件的根元素就是beans --> 4 <beans xmlns="http://www.springframework.org/schema/beans" 5 xmlns:p="http://www.springframework.org/schema/p" 6 xmlns:util="http://www.springframework.org/schema/util" 7 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 8 xsi:schemaLocation="http://www.springframework.org/schema/beans 9 http://www.springframework.org/schema/beans/spring-beans.xsd 10 11 http://www.springframework.org/schema/util 12 http://www.springframework.org/schema/util/spring-util.xsd"> 13 14 <bean id="person" class="com.csu.spring.getter_test.Person" scope="prototype"> 15 <property name="age"> 16 <value>30</value> 17 </property> 18 19 <property name="son"> 20 <bean class="com.csu.spring.getter_test.Son"> 21 <property name="age"> 22 <value>16</value> 23 </property> 24 </bean> 25 </property> 26 </bean> 27 28 <!--如下将会将person的属性son的属性age传入son1实例的age属性--> 29 <bean id="son1" class="com.csu.spring.getter_test.Son"> 30 <property name="age"> 31 <!--以下是访问bean属性的简单方式,这样可以将person这个bean的age属性赋值给son1这个bean的age属性--> 32 <!-- 此处的id是指person.getSon().getAge()的返回值 --> 33 <bean id="person.son.age" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/> 34 </property> 35 </bean> 36 37 <!-- 以下将会获得结果son,它将是person bean的son的数值--> 38 <bean id="son2" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> 39 <property name="targetBeanName"> 40 <value>person</value> 41 </property> 42 <property name="propertyPath"> 43 <value>son</value> 44 </property> 45 </bean> 46 47 <!-- 以下将会获得结果16,它将是person bean的son的age属性--> 48 <bean id="son3" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> 49 <property name="targetBeanName"> 50 <value>person</value> 51 </property> 52 <property name="propertyPath"> 53 <value>son.age</value> 54 </property> 55 </bean> 56 57 <!-- 以下会获得结果为30 ,它将是获得该bean的内部bean的age属性--> 58 <bean id="son4" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> 59 <property name="targetObject"> 60 <bean class="com.csu.spring.getter_test.Person"> 61 <property name="age"> 62 <value>30</value> 63 </property> 64 </bean> 65 </property> 66 <property name="propertyPath"> 67 <value>age</value> 68 </property> 69 </bean> 70 71 <!--访问实例Field的 --> 72 <bean id="dog" class="com.csu.spring.getter_test.Dog" p:age="2"/> 73 <bean id="age" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" 74 p:targetObject-ref="dog" p:targetField="age"/> 75 76 <!-- 调用普通方法 --> 77 <bean id="jf" class="javax.swing.JFrame" p:title="我的窗口"/> 78 <bean class="org.springframework.beans.factory.config.MethodInvokingBean" 79 p:targetObject-ref="jf" 80 p:targetMethod="setBounds"><!-- targetMethod就是指定方法名 ,不要对方法名进行任何修改--> 81 <property name="arguments"> 82 <list> 83 <value>40</value> 84 <value>40</value> 85 <value>200</value> 86 <value>300</value> 87 </list> 88 </property> 89 </bean> 90 <bean class="org.springframework.beans.factory.config.MethodInvokingBean" 91 p:targetObject-ref="jf" 92 p:targetMethod="add"><!-- targetMethod就是指定方法名 ,不要对方法名进行任何修改--> 93 <property name="arguments"> 94 <list> 95 <bean class="javax.swing.JButton"> 96 <constructor-arg value="文本框"/> 97 </bean> 98 <value>North</value> 99 </list> 100 </property> 101 </bean> 102 103 <bean class="org.springframework.beans.factory.config.MethodInvokingBean" 104 p:targetObject-ref="jf" 105 p:targetMethod="add"><!-- targetMethod就是指定方法名 ,不要对方法名进行任何修改--> 106 <property name="arguments"> 107 <list> 108 <bean class="javax.swing.JButton"> 109 <constructor-arg value="我的按钮"/> 110 </bean> 111 112 <value>South</value> 113 </list> 114 </property> 115 </bean> 116 117 118 <bean class="org.springframework.beans.factory.config.MethodInvokingBean" 119 p:targetObject-ref="jf" 120 p:targetMethod="setVisible"><!-- targetMethod就是指定方法名 ,不要对方法名进行任何修改--> 121 <property name="arguments"> 122 <list> 123 <value>true</value> 124 </list> 125 </property> 126 </bean> 127 128 <bean id="out" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" 129 p:targetClass="java.lang.System" 130 p:targetField="out"/> 131 132 <util:constant id="out2" static-field="java.lang.System.out" /> 133 <util:constant id="out3" static-field="java.sql.Connection.TRANSACTION_SERIALIZABLE"/> 134 <util:property-path id="pAge" path="person.age"/> 135 <util:list id="mylist" list-class="java.util.ArrayList"> 136 <value>哈哈</value> 137 <bean class="java.util.Date"></bean> 138 <value></value> 139 </util:list> 140 141 142 </beans>