一、构造器参数注入
1. 普通方式注入。
<bean id="xxxXxxx" class="xxx.xxx.xxx.XxxXxx">
<constructor-arg index="0" ref="xxxXxx"/>
<constructor-arg index="1" value="xxx"/>
</bean>
说明:index为构造器参数顺序,从“0”开始。ref引用对象类型参数,value引用基本数据类型和String类型参数。
2. 实例工厂方法注入<bean id="beanFactory" class="xxx.xxx.xxx.BeanFactory"/>
<bean id="xxxXxxx" factory-bean="beanFactory" factory-method="initUserService">
<constructor-arg index="1" ref="userDao"/>
<constructor-arg index="0" value="1"/>
</bean>
说明:factory-bean指明工厂类,factory-method指明实例化对象使用的工厂方法。index为工厂方法参数的顺序,从“0“开始。
3. 静态工厂方法注入
<bean id="xxxXxxx" class="xxx.xxx.xxx.BeanFactory" factory-method="initUserService">
<constructor-arg index="1" ref="userDao"/>
<constructor-arg index="0" value="1"/>
</bean>
说明:class属性限定静态工厂类的全类名,factory-method属性指明实例化对象的静态方法,index为方法参数顺序,从”0“开始。
附:测试代码
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
XxxXxx xxxXxx = context.getBean("xxxXxx",XxxXxx.class);
xxxXxx.method();
二、setter方法注入
<bean id="bean" class="cn.javass.spring.chapter3.HelloImpl4">
<property name="message" value="Hello World!"/>
<property name="index">
<value>1</value>
</property>
</bean>
说明:name属性与setter方法对应,例如name=”message“,则setter方法为"setMessage"。value属性注入基本数据类型和String类型的值,可以用ref注入对象类型。
三、常量注入
<property name="message" value="Hello World!"/>
或
<property name="index"><value>1</value></property>
注:Spring类型转换系统对于boolean类型进行了容错处理,除了可以使用“true/false”标准的Java值进行注入,还能使用“yes/no”、“on/off”、“1/0”来代表“真/假”,所以遇到这种类似问题不要觉得配置错了,而是Spring容错做的非常好。
四、集合注入(List,Set,Map,数组)
用以下配置方式说明各种集合注入方式
<bean id="euroCup" class="com.xaccp.ecup.EuropeanCup">
<property name="groupA">
<list>
<ref bean="team1"/>
<ref bean="team2"/>
<ref bean="team3"/>
<ref bean="team4"/>
</list>
</property>
<property name="groupB">
<set>
<ref bean="team1"/>
<ref bean="team2"/>
<ref bean="team3"/>
<ref bean="team4"/>
</set>
</property>
<property name="groupC">
<map>
<entry key="team1" value-ref="team1"></entry>
<entry key="team2" value-ref="team2"></entry>
<entry key="team3" value-ref="team3"></entry>
<entry key="team4" value-ref="team4"></entry>
</map>
</property>
<property name="groupD">
<array>
<value>捷克</value>
<value>克罗地亚</value>
<value>西班牙</value>
<value>荷兰</value>
</array>
</property>
</bean>
<bean id="team1" class="com.xaccp.ecup.Team">
<property name="name" value="德国"></property>
</bean>
<bean id="team2" class="com.xaccp.ecup.Team">
<property name="name" value="意大利"></property>
</bean>
<bean id="team3" class="com.xaccp.ecup.Team">
<constructor-arg value="法国">
</constructor-arg>
</bean>
<bean id="team4" class="com.xaccp.ecup.Team">
<property name="name" value="葡萄牙"></property>
</bean>
五、内部Bean定义
内部bean即在<property>或<constructor-arg>之下用<bean>定义的Bean。内部Bean即使定义了“id”或“name”属性,外部也无法引用。
<constructor-arg index="0">
<bean class="cn.com.enorth.dao.impl.TestDaoImpl"></bean>
</constructor-arg>
六、Spring通过<null/>标签注入null值
<property name="message"><null/></property>
七、使用p命名空间简化setter注入
注入基本数据类型
<bean id="..." class="..." p:id="value"/>
以上等价于
<bean id="..." class="...">
<property name="id" value="value"/>
</bean>
注入对象数据类型
<bean id="..." class="..." p:id-ref="bean"/>
以上等价于
<bean id="..." class="...">
<property name="id" ref="bean"/>
</bean>
八、注入File对象和指定初始化方法、销毁方法
<property name="file" value="D:/text.txt" />
Spring容器能自动把字符串转换成java.io.File。
<bean id="..." class="..." init-method="init" destroy-method="destroy"/>
init-method属性指定初始化方法,在构造器和setter注入完成之后执行。
destroy-method属性指定销毁方法,只用“singleton”作用域的Bean能确保有效。要让销毁方法起作用还必须在实例化Spring容器之后注册销毁回调,如下:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//注册销毁回调,否则销毁方法不起作用
context.registerShutdownHook();
九、自动装配
1.byName易混淆:作用于setter注入。例如有“setHelloWorld”方法,则Spring容器会查找名为“helloWorld”的bean进行注入,如果找不到bean什么也不注入。注意这里不是按照私有字段的“name”来注入的。
2.byType说明:作用于setter注入。例如有“setHelloWorld”方法,则Spring容器会查找类型为“HelloWorld”的bean进行注入,如果找不到bean什么也不注入。如果找到多个符合条件的bean,将优先注入”primary“属性为true的bean,也可以设置<bean>的属性“autowire-candidate”为false来放弃作为自动匹配候选者。
3.constructor:按照“byType”方式进行构造器注入,有多个bean符合要求时甄选规则遵循byType的甄选规则,并且只能用于构造器注入。4.<beans>的“default-autowire”属性可设置全局的自动装配方式,“default-autowire-candidates”属性可设置模式化全局自动装配,例如指定“*Service,*Dao",则只有符合这些模式的bean才会作为自动装配的候选者。
5.数组、集合(Set,Collection,List)、字典(Map)类型自动装配。如果是接口类型,将根据泛型匹配所有候选者注入到数组或集合中,如“List<HelloWorld> list"将选择所有符合条件的“HelloWorld”类型的bean注入到list中。而如果是接口的具体实现类,如”ArrayList<HelloWorld> list"将选择一个类型为ArrayList的bean注入到list中。
十、方法注入
1. 查找方法注入
在<bean>标签中配置< lookup-method name="..." bean="..."/>,则Spring会拦截该Bean中指定的方法,返回bean属性指定的对象,而方法本身的内容不会执行。
被拦截的方法格式。访问级别是public或者protect,可以是抽象方法,必须有返回值,必须是无参方法,非final类型,其所在类也是非final类型。
方法注入主要用于应对“singleton”作用域的Bean需要其他作用域的Bean的情形。使用Spring查找方法注入无需修改任何代码就能获得需要的其他作用域的Bean。
2. 替换方法注入
和查找方法注入不同,前者主要用来替换方法的返回值,后者主要用来替换方法体。
首先新建MethodReplacer接口的实现类,用于完全替换被拦截方法的方法体和返回值,“reimplement”方法负责实现这一功能。方法参数obj为包含被拦截方法的对象,method为被拦截的方法,args为方法参数。注意不要再通过反射('method.onvoke(obj,new String[]{"str"})')调用原来的方法,这样会产生死循环。如果原方法的返回类型为void,在实现中返回null。然后在<bean>中配置替换方法,子标签<arg-type>必须配置,它指定原来方法的参数类型。
<replaced-method name="方法名" replacer="MethodReplacer实现类">
<arg-type>参数类型</arg-type>
</replaced-method>