首先写接口类:
package com.action; public interface HelloApi { void sayHello(); }
其次写实现类:
package com.action; public class HelloApiImpl implements HelloApi{ private String message; private int index; public HelloApiImpl(String message,int index){ this.message = message; this.index = index; } @Override public void sayHello() { System.out.println(index+" : "+message); } }
第一阶段:通过构造方法注入的各种方式
第一,配置xml文件,从下面开始的每一个xml文件都省略掉beans了。
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- 通过构造器参数索引方式依赖注入 --> <bean id="byIndex" class="com.action.HelloApiImpl"> <constructor-arg index="0" value="Hello Spring byIndex..."></constructor-arg> <constructor-arg index="1" value="1"></constructor-arg> </bean> <!-- 通过构造器参数数据类型方式依赖注入 --> <bean id="byType" class="com.action.HelloApiImpl"> <constructor-arg type="java.lang.String" value="Hello Spring byType..."></constructor-arg> <constructor-arg type="int" value="2"></constructor-arg> </bean> <!-- 通过构造器参数名称方式依赖注入 --> <bean id="byName" class="com.action.HelloApiImpl"> <constructor-arg name="message" value="Hello Spring byName..."></constructor-arg> <constructor-arg name="index" value="3"></constructor-arg> </bean> </beans>
第二:写测试类。
package com.action; import org.springframework.beans.factory.beanfactory; import org.springframework.context.support.ClassPathXmlApplicationContext; public class DependencyInjectTest { public static void main(String[] args) { beanfactory beanfactory = new ClassPathXmlApplicationContext("com/resource/ConstructorDependencyInject.xml"); HelloApi byIndex = beanfactory.getBean("byIndex",HelloApi.class); byIndex.sayHello(); HelloApi byType = beanfactory.getBean("byType",HelloApi.class); byType.sayHello(); HelloApi byName = beanfactory.getBean("byName",HelloApi.class); byName.sayHello(); /*通过参数名称依赖注入的时候,需要开启调试模式。以下为比较正式的解释: * 构造器注入可以根据参数索引注入、参数类型注入或Spring3支持的参数名注入,但参数名注入是有限制的, * 需要使用在编译程序时打开调试模式(即在编译时使用“javac –g:vars”在class文件中生成变量调试信息, * 默认是不包含变量调试信息的,从而能获取参数名字,否则获取不到参数名字) * 或在构造器上使用@ConstructorProperties(java.beans.ConstructorProperties)注解来指定参数名。 * * 通过构造器参数名字注入方式,先确保编译时class文件包含“变量信息” * 在myeclipse中的调整步骤为:进入项目属性,java compiler,下面add varible……勾选上。 * */ } }
第三,静态工厂类和实例工厂类(测试类省略)
静态工厂
package com.action; public class DependencyInjectByFactory { //静态工厂类 private static HelloApi newInstance(String message,int index){ return new HelloApiImpl(message,index); } }xml文件
<!-- 通过构造器参数索引方式依赖注入 --> <bean id="byIndex" class="com.action.DependencyInjectByFactory" factory-method="newInstance"> <constructor-arg index="0" value="Hello Spring byIndex..."></constructor-arg> <constructor-arg index="1" value="1"></constructor-arg> </bean> <!-- 通过构造器参数数据类型方式依赖注入 --> <bean id="byType" class="com.action.DependencyInjectByFactory" factory-method="newInstance"> <constructor-arg type="java.lang.String" value="Hello Spring byType..."></constructor-arg> <constructor-arg type="int" value="2"></constructor-arg> </bean> <!-- 通过构造器参数名称方式依赖注入 --> <bean id="byName" class="com.action.DependencyInjectByFactory" factory-method="newInstance"> <constructor-arg name="message" value="Hello Spring byName..."></constructor-arg> <constructor-arg name="index" value="3"></constructor-arg> </bean>实例工厂
package com.action; public class DependencyByInstanceFactory { //实例工厂类 public HelloApi newInstance(String message,index); } }xml文件
<bean id="DependencyByInstanceFactory" class="com.action.DependencyByInstanceFactory"></bean> <!-- 通过构造器参数索引方式依赖注入 --> <bean id="byIndex" factory-bean="DependencyByInstanceFactory" factory-method="newInstance"> <constructor-arg index="0" value="Hello Spring byIndex..."></constructor-arg> <constructor-arg index="1" value="1"></constructor-arg> </bean> <!-- 通过构造器参数数据类型方式依赖注入 --> <bean id="byType" factory-bean="DependencyByInstanceFactory" factory-method="newInstance"> <constructor-arg type="java.lang.String" value="Hello Spring byType..."></constructor-arg> <constructor-arg type="int" value="2"></constructor-arg> </bean> <!-- 通过构造器参数名称方式依赖注入 --> <bean id="byName" factory-bean="DependencyByInstanceFactory" factory-method="newInstance"> <constructor-arg name="message" value="Hello Spring byName..."></constructor-arg> <constructor-arg name="index" value="3"></constructor-arg> </bean>这个时候所有的不同,各种方法的各种优势都展现出来了。
对于setter注入的初步了解,测试类省略。
实现类
package com.action; public class HelloApiSet implements HelloApi{ private String message; private int index; public void setMessage(String message) { this.message = message; } public void setIndex(int index) { this.index = index; } public void sayHello(){ System.out.println(index+" : "+message); } }xml
<bean id="bean" class="com.action.HelloApiSet"> <property name="message" value="Hello TestSet"></property> <property name="index" value="123"></property> </bean>
常量注入
<property name="index" value="123"></property> <property name="index"><value>123</value></property>第一种和第二种是表述方式是一样的,第二种中的123是以字符串形式传入的,由spring自动转换成需要的类型,如果转换错误会抛出相应的异常。
Spring类型转换系统对于boolean类型进行了容错处理,除了可以使用“true/false”标准的Java值进行注入,还能使用“yes/no”、“on/off”、“1/0”来代表“对/错”。
先写类。
package com.action; public class BooleanBean { private boolean success; public void setSuccess(boolean success){ this.success = success; } public void isSuccess(){ System.out.println(success); } }xml
<!-- true/false 以下都是按“对/错”的位置排列的--> <bean id="bean1" class="com.action.BooleanBean"> <property name="success" value="true"></property> </bean> <!-- yes/no --> <bean id="bean2" class="com.action.BooleanBean"> <property name="success" value="yes"></property> </bean> <!-- on/off --> <bean id="bean3" class="com.action.BooleanBean"> <property name="success" value="on"></property> </bean> <!-- 1/0 --> <bean id="bean4" class="com.action.BooleanBean"> <property name="success" value="1"></property> </bean>测试类省略。
package com.action; import java.util.List; public class ListBean { private List<String> values; public List<String> getValues() { return values; } public void setValues(List<String> values) { this.values = values; } }配位文件xml
<bean name="ListBean" class="com.action.ListBean"> <property name="values"> <list> <value>1</value> <value>2</value> <value>3</value> </list> </property> </bean>测试类
package com.action; import org.springframework.beans.factory.beanfactory; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestListBean { public static void main(String[] args) { beanfactory beanfactory = new ClassPathXmlApplicationContext("com/resource/ListInject.xml"); ListBean listBean = beanfactory.getBean("ListBean",ListBean.class); System.out.println(listBean.getValues().size()); // for (Iterator<String> iterator = listBean.getValues().iterator(); iterator.hasNext();) { // String type = (String) iterator.next(); // System.out.println(type); // } } }当注入Set的时候大致如此,xml文件里面的list改写成Set。数组的时候改成array, 二维数组的话array里面可以还有array。最后说map,map的时候需要指定一些东西。
<bean name="MapBean" class="com.action.MapBean"> <property name="values"> <map key-type="java.lang.String" value-type="java.lang.String"> <entry> <key><value>aaa</value></key> <value>bbb</value> </entry> <entry key="ccc" value="ddd"></entry> </map> </property> </bean>
public class MapBean { private Map<String,String> values; public Map<String,String> getValues() { return values; } public void setValues(Map<String,String> values) { this.values = values; } }
public class TestMapBean { public static void main(String[] args) { beanfactory beanfactory = new ClassPathXmlApplicationContext("com/resource/ListInject.xml"); MapBean mapBean = beanfactory.getBean("MapBean",MapBean.class); for (Iterator<Map.Entry<String,String>> iterator = mapBean.getValues().entrySet().iterator(); iterator.hasNext();) { Map.Entry<String,String> temp = iterator.next(); System.out.println(temp.getKey()+"==="+temp.getValue()); } } }
引用其他Bean
package com.action; public class HelloImpl implements HelloApi{ @Override public void sayHello() { System.out.println("I love you,Spring!"); } }
package com.action; public class DecoratorHelloApi implements HelloApi { private HelloApi helloApi1; //无参 public DecoratorHelloApi() { } //有参 public DecoratorHelloApi(HelloApi helloApi) { this.helloApi1 = helloApi; } //setter方法 public void setHelloApi(HelloApi helloApi) { this.helloApi1 = helloApi; } @Override public void sayHello() { System.out.println("===========装饰一下============="); helloApi1.sayHello(); System.out.println("===========装饰一下============="); } }
<!-- 定义依赖bean --> <bean id="helloImpl" class="com.action.HelloImpl"></bean> <!-- 下面两种方式注入都可以分为三小种,类型,索引和名字 --> <!-- 通过构造器注入 --> <bean id="bean1" class="com.action.DecoratorHelloApi"> <constructor-arg index="0" ref="helloImpl"></constructor-arg> </bean> <!-- 通过setter注入 --> <bean id="bean2" class="com.action.DecoratorHelloApi"> <property name="helloApi"><!-- 注意最好属性名和依赖bean的名字别一样,妈的我找错找了很久 --> <ref bean="helloImpl"/> </property> </bean>
<ref local>和<ref parent>的配置。(这个有点乱……)
package com.action; public class HelloImpl implements HelloApi{ private String message; private String name; public HelloImpl() { } public HelloImpl(String message,String name) { this.name = name; this.message = message; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } @Override public void sayHello() { System.out.println(message+"==="+name); } }
package com.action; import com.action.HelloApi; public class DecoratorHelloApi implements HelloApi { private HelloApi helloApi1; //无参 public DecoratorHelloApi() { } //有参 public DecoratorHelloApi(HelloApi helloApi) { this.helloApi1 = helloApi; } //setter方法 public void setHelloApi(HelloApi helloApi) { this.helloApi1 = helloApi; } @Override public void sayHello() { System.out.println("===========装饰一下============="); helloApi1.sayHello(); System.out.println("===========装饰一下============="); } }
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean id="helloApi" class="com.action.HelloImpl"> <property name="message" value="Hello"></property> <property name="name" value="parent"></property> </bean> </beans>
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean id="helloApi" class="com.action.HelloImpl"> <property name="message" value="Hello"></property> <property name="name" value="local"></property> </bean> <!-- 通过parent注入 --> <bean id="bean1" class="com.action.DecoratorHelloApi"> <constructor-arg index="0"> <ref parent="helloApi" ></ref> </constructor-arg> </bean> <!-- 通过local注入 --> <bean id="bean2" class="com.action.DecoratorHelloApi"> <!-- <property name="helloApi" ref="helloApi"></property> --> <!-- 默认情况下是先查当前 --> <property name="helloApi"> <ref local="helloApi" /> </property> </bean> </beans>
package com.action; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestLocalAndparentBeanInject { public static void main(String[] args) { //初始化父容器 ApplicationContext parentContext = new ClassPathXmlApplicationContext("com/resource/parentBeanInject.xml"); //初始化当前容器 应该是这句话定义父子关系的 ApplicationContext beanContext = new ClassPathXmlApplicationContext(new String[]{"com/resource/localBeanInject.xml"},parentContext); HelloApi helloApi1 = beanContext.getBean("bean1",HelloApi.class); helloApi1.sayHello();//该helloApi引用parent HelloApi helloApi2 = beanContext.getBean("bean2",HelloApi.class); helloApi2.sayHello();//该helloApi2引用local } }
package com.action; public class HelloImpl implements HelloApi { @Override public void sayHello() { System.out.println("Hello World!"); } }
package com.action; public class HelloApiDecorator implements HelloApi { private HelloApi helloApi; //空参构造器 public HelloApiDecorator() { } //有参构造器 public HelloApiDecorator(HelloApi helloApi) { this.helloApi = helloApi; } public void setHelloApi(HelloApi helloApi) { this.helloApi = helloApi; } @Override public void sayHello() { System.out.println("==========装饰一下==========="); helloApi.sayHello(); System.out.println("==========装饰一下==========="); } }
<bean id="bean" class="com.action.HelloApiDecorator"> <property name="helloApi"> <bean id="helloApi" class="com.action.HelloImpl"></bean> </property> </bean>
public class TestInnerBeanInject { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("com/resource/innerBeanInject.xml"); HelloApi ha = ac.getBean("bean",HelloApi.class); ha.sayHello(); } }
注入null值 可以通过类似方式注入
<bean id="bean2" class="com.action.DecoratorHelloApi"> <property name="message"><null/></property> </bean>
对象图导航注入支持(这个应该意义不大,我另写一篇吧,把这个完结了。)
配置简写
(以下为转载。)
一、构造器注入:
1)常量值
简写:<constructor-arg index="0" value="常量"/>
全写:<constructor-arg index="0"><value>常量</value></constructor-arg>
2)引用
简写:<constructor-arg index="0" ref="引用"/>
全写:<constructor-arg index="0"><ref bean="引用"/></constructor-arg>
二、setter注入:
1)常量值
简写:<property name="message" value="常量"/>
全写:<property name="message"><value>常量</value></ property>
2)引用
简写:<property name="message" ref="引用"/>
全写:<property name="message"><ref bean="引用"/></ property>
3)数组:<array>没有简写形式
4)列表:<list>没有简写形式
5)集合:<set>没有简写形式
6)字典
简写:<map>
<entry key="键常量" value="值常量"/>
<entry key-ref="键引用" value-ref="值引用"/>
</map>
全写:<map>
<entry><key><value>键常量</value></key><value>值常量</value></entry>
<entry><key><ref bean="键引用"/></key><ref bean="值引用"/></entry>
</map>
7)Properties:没有简写形式
三、使用p命名空间简化setter注入:
使用p命名空间来简化setter注入,具体使用如下:
- xmlns:p="http://www.springframework.org/schema/p":首先指定p命名空间;
- <bean id="……" class="……" p:id="value"/>:常量setter注入方式,其等价于<property name="id" value="value"/>;
- <bean id="……" class="……" p:id-ref="bean1"/>:引用setter注入方式,其等价于<property name="id" ref="bean1"/>。
本来就是比着一本书摘录的,写就是为了自己以后复习使用,这一章写的太长了,而且又乱到时候读的时候一定有麻烦。以后得注意前后呼应的格式了。