时间 | 内容 | |
---|---|---|
11.03 | Bean的装配 |
1、Spring配置概述
下图描述了Spring容器、Bean配置信息、Bean实现类、及应用程序这4者的关系:
Bean的配置信息定义了Bean的实现及依赖关系,spring 容器根据各种形式的Bean配置信息在容器内部建立Bean定义注册表,然后根据注册表加载、实例化Bean,并建立Bean和Bean的依赖关系,最后将这些准备就绪的Bean放到Bean缓存池中,一共外层的应用程序进行调用。
2、基于XML的配置
Spring基于Schema配置方案是不同类型的配置拥有了自己的命名空间,是配置文件更有拓展性。
基于Schema的配置格式,文件头的声明会复杂一些,如下图:
Schema在文档中根据节点中通过xmlns对文档中的命名空间进行声明。在上图的代码中定义了三个命名空间:
- 默认命名空间:没有空间名,用于Spring Bean的定义;
- xsi命名空间:该命名空间用于为每个文档中命名空间制定相应的Schema样式文件,是标准定义的标准命名空间;
- aop命名空间:该命名空间是spring 配置AOP的命名空间,是用户自定义的命名空间。
命名空间的定义分为两个步骤:1、指定命名空间的名称,需要指定命名空间的缩略名和全名,即xmlns:缩略名=“全限定名”;2、是制定命名空间的Schema文档样式文件的位置,用空格或回车进行分隔。
3、Bean的基本配置
3.1装配一个Bean
通过容器的getBean(id)即可获得对应的Bean。
下面基于XMl的配置文件定义了两个简单的Bean:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="car" class="com.cahnghong.simple.Car"/>
<bean id="boss" class="com.changhong.simple.Boss"/>
</beans>
在这段配置信息中提供了实例化Car和Boss这两个Bean必需的信息,Spring IoC完全可以据此创建这两个Bean的实例。
3.2Bean的命名
一般情况下,在配置一个Bean时,需要指定一个id属性作为Bean的名称。id在IoC容器中是唯一的。id的命名规范:以字母开头,后面可以说字母、数字、连字符、下划线以及句号、冒号等完整结束的符号(逗号、空格等非完整结束符是非法的)。也可以采用Bean的name属性进行命名,name在字符上没有限制。Spring不允许出现两个相同的id,却可以出现相同的name,getBean(beanName)时,后面的bean 将覆盖前面的bean。所以尽量使用id命名的Bean。id为Bean的唯一名称才是康庄大道。
4、依赖注入
Spring支持两种依赖注入方式,分别是属性注入和构造函数注入。此外,还支持工厂方法注入方式。
4.1属性注入
属性注入就是通过setXxx()方法注入Bean的属性值或依赖对象,属性注入具有可选择性和高灵活性,所以它是最长采用的注入方式。
属性注入要求Bean提供一个默认的构造函数,并为需要注入的属性提供对应的Setter方法。spring 先调用Bean的默认构造函数实例化Bean对象没然后通过反射的方式调用Setter方法注入属性值,例如:
Car.java
public class Car {
private int maxSpeed;
private String brand;
private double price;
setter(){
}
}
applicationContext-beans.xml
<beans>
......
<!-- 扫描类包,将标注Spring注解的类自动转化Bean,同时完成Bean的注入 -->
<context:annotation-config/>
<context:component-scan base-package="com.changhong"/>
<import resource="applicationContext.xml" />
<bean id="car" class="com.changhong.ditype.Car">
<property name="maxSpeed" value="2000"></property>
<property name="brand" value="宝马X6"></property>
<property name="price" value="20000000"></property>
</bean>
</beans>
JavaBean关于属性命名的特殊规范
Spring陪着紫文件中元素所指定的属性名和Bean实现类的Setter方法满足Sun JavaBean的属性命名规范:xxx属性对应setXxx()方法。属性命名时变量的前两个字母要么全部大写要么全部小写。
4.2构造函数注入
构造函数注入保证一些必要的属性在Bean实例化时就得到设置,它保证了Bean实例在实例化后就可使用。
按类型匹配入参
如果任何可用的Car对象都必须提供brand和price值,如果使用属性注入的方式智能人为的在配置时提供保证而不能在语法级提供保证,这是通过构造函数注入就可很好的满足这一要求。使用构造函数注入的前提是Bean必须提供带参的构造器:写构造函数时,必须在类中重写默认的构造函数
public Car(){
}
public Car(int maxSpeed,String brand,double price){
this.maxSpeed=maxSpeed;
this.brand=brand;
this.price=price;
}
xml
<bean id="car1" class="com.changhong.ditype.Car">
<constructor-arg type="int">
<value>200</value>
</constructor-arg>
<constructor-arg type="java.lang.String">
<value>红旗111</value>
</constructor-arg>
<constructor-arg type="double">
<value>1230000</value>
</constructor-arg>
</bean>
按索引匹配入参
如果在Car的构造函数中两个入参的类型相同,仅通过type就无法确定对应关系,这时就需要入参索引的方式进行确定。