1. Bean对象属性值的注入
在Spring中对Bean属性赋值的过程我们称之为依赖注入。
Spring应用中为Bean的属性注入值的方式有两种:
1)set注入 set注入式通过对象的set方法为对象属性赋值
2)构造注入 构造注入为通过bean对象的构造方法为属性注入值
1.1 直接量值的注入
Spring 直接量值的注入指的是通过Spring IOC为对象的8种封装类以及String类型的属性注入值。
例如:
定义OpenDataSouce类
public class OpenDataSource {
private String driverClassName;
private String url;
private String username;
private String password;
private String maxIdle;
private String maxActive;
public OpenDataSource() {}
public OpenDataSource(int maxIdle,int maxActive){
this.maxIdle=maxIdle;
this.maxActive=maxActive;
}
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUser(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
//…
}
配置OpenDataSource类并通过set方法为对象属性赋值。
例如:
如下配置会先调用bean对象的无参构造函数构建对象,然后通过set方法为属性赋值。
<bean id="dataSource" class="com.jt.common.utils.OpenDataSource">
<property name="driverClassName" value="com.jdbc.mysql.Driver"/>
<property name="url" value="jdbc:mysql:///test"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
当然假如对象提供了对应的构造方法也可以通过指定构造方法为属性注入值。
例如:
在如下配置中可以调用OpenDataSource对象的有两个参数的构造函数构建对象
<bean id="openDataSource" class="com.jt.common.utils.OpenDataSource">
<!-- 默认按照构造方法参数顺序注入值
说明:配置时有几个constructor-arg就是
要调用带及格参数的构造函数
-->
<constructor-arg value="10"/>
<constructor-arg value="100"/>
</bean>
实际项目中也可以构造注入和set注入混合使用。
<bean id="dataSource" class="com.jt.common.utils.OpenDataSource">
<constructor-arg value="10"/>
<constructor-arg value="100"/>
<property name="driverClassName" value="com.jdbc.mysql.Driver"/>
<property name="url" value="jdbc:mysql:///test"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
说明:
依赖注入时可以将配置信息提取到properties文件中,然后通过spring表达式#{id.key}的方式提取数据。
在类路径下定义一个configs.properties文件,内容如下:
jdbcDriver= com.mysql.jdbc.Driver
jdbcUrl= jdbc:mysql:///test
jdbcUser= root
jdbcPassword=123456
在spring的配置文件中配置configs.properties文件
<util:properties id="cfg" location="classpath:configs.properties"/>
在bean中为属性注入值时使用spring 表达式
<bean id="dataSource" class="beans.OpenDataSource">
<property name="driverClassName" value="#{cfg.jdbcDriver}"/>
<property name="url" value="#{cfg.jdbcUrl}"/>
<property name="username" value="#{cfg.jdbcUser}"/>
<property name="password" value="#{cfg.jdbcPassword}"/>
</bean>
其中#为spring表达式特殊标记,{}为表达式内容,cfg为util:properties 标签中定义的id. jdbcUser、jdbcPassword为配置文件等号左边的key
1.2 集合对象值的注入
Spring IOC 如何为集合类型的对象属性注入值?
例如:
public class Container {
private List<String> list;
private Map<String,Object> map;
private Properties properties;
public void setList(List<String> list) {
this.list = list;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
...
}
Spring 配置文件中为对象属性注入值
<bean id="collection" class="beans.Container">
<property name="list">
<list>
<value>A</value>
<value>B</value>
</list>
</property>
<property name="map">
<map>
<entry key="k1" value="100" />
<entry key="k2" value="300" />
</map>
</property>
<property name="properties">
<props>
<prop key="username">root</prop>
<prop key="password">123456</prop>
</props>
</property>
</bean>
1.3 依赖对象值的注入
实际项目会存在很多个Bean对象,这些对象之间会存在一定依赖关系。
当某个Bean对象依赖于其它Bean对象,可以通过spring按照一定的规则(例如按类型或者按名字)进行依赖查找然后进行值的注入。
例如:
现有一生产者对象(Producer),此对象关联一容器(Container)对象,然后可以通过容器对象存储相关数据。
其代码设计如下:
类的设计
package com.jt.common.utils;
/**生产者对象(负责向容器放数据)*/
public class Producer {//IOC(工厂,容器)
/**生产者关联一个容器对象(目的是要向此容器放数据)*/
private Container container;
public void setContainer(Container container) {
this.container = container;
}
public Container getContainer() {
return container;
}
}
类的基本配置
<bean id="producer" class="com.jt.common.utils.Producer">
<!-- 借助ref属性从容器中获取一个id为container
的对象然后赋值给Producer的container属性 -->
<property name="Container" ref="container"/>
</bean>
单元测试
public class TestProducer01 extends TestBase{
@Test
public void testProducer(){
//1.获取生产者对象
Producer pro=ctx.getBean("producer",Producer.class);
Assert.assertNotEquals(null, pro);
//2.获取生产者关联的容器对象
Container container=pro.getContainer();
Assert.assertNotEquals(null, container);
//3.向容器放数据
container.getMap().put("mysql", 100);
container.getList().add("张三");
}
}
2. Bean对象属性值装配
Spring 应用中还可以按照一定规则自动为对象属性注入值(自动装配),此机制实现的可以借助Bean标签中的autowire属性进行配置.此属性的值如下几个:
- default : 不执行自动装配(默认)
- byName: 按属性名对应的set方法名进行自动装配(自动为属性注入值)
- byType: 按属性类型找对应set方法(与方法参数类型匹配)然后进行装配
- constructor:按构造方法参数类型进行装配
例如:
<bean id="producer" class="com.jt.common.beans.Producer"
autowire="byType">
</bean>
此代码中的自动装配是按照Producer类中相关属性类型查找对应参数类型的set方法,然后再依据其类型从spring容器中查找对应类型的bean对象,最后调用对应set方法进行值的注入。
注:了解基于xml方式配置的自动装配机制(重点在注解方式的应用)