首先写接口类:
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,int index){
return new HelloApiImpl(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"/>。
本来就是比着一本书摘录的,写就是为了自己以后复习使用,这一章写的太长了,而且又乱到时候读的时候一定有麻烦。以后得注意前后呼应的格式了。