查看下面两个 Employee 的配置,其中 dept 属性是重复的:
<bean id="dept" class="com.parent.bean.Department">
<property name="deptId" value="100"/>
<property name="deptName" value="IT"/>
</bean>
<bean id="emp01" class="com.parent.bean.Employee">
<property name="empId" value="1001"/>
<property name="empName" value="Tom"/>
<property name="age" value="20"/>
<!-- 重复的属性值 -->
<property name="dept" ref="dept"/>
</bean>
<bean id="emp02" class="com.parent.bean.Employee">
<property name="empId" value="1002"/>
<property name="empName" value="Jerry"/>
<property name="age" value="25"/>
<!-- 重复的属性值 -->
<property name="dept" ref="dept"/>
</bean>
配置信息的继承:
<bean id="dept" class="com.parent.bean.Department">
<property name="deptId" value="100"/>
<property name="deptName" value="IT"/>
</bean>
<bean id="emp01" class="com.parent.bean.Employee">
<property name="empId" value="1001"/>
<property name="empName" value="Tom"/>
<property name="age" value="20"/>
<!-- 重复的属性值 -->
<property name="dept" ref="dept"/>
</bean>
<!-- 以emp01作为父bean,继承后可以省略公共属性值的配置 -->
<bean id="emp02" parent="emp01">
<property name="empId" value="1002"/>
<property name="empName" value="Jerry"/>
<property name="age" value="25"/>
</bean>
Spring 允许继承 bean 的配置,被继承的 bean 称为父 bean。继承这个父 bean 的 bean 称为子 bean 子 bean 从父 bean 中继承配置,包括 bean 的属性配置子 bean 也可以覆盖从父 bean 继承过来的配置。
父 bean 可以作为配置模板,也可以作为 bean 实例。若只想把父 bean 作为模板,可以设置的 abstract 属性为 true,这样 Spring 将不会实例化这个 bean。如果一个 bean 的 class 属性没有指定,则必须是抽象 bean,并不是元素里的所有属性都会被继承。比如:autowire,abstract 等。也可以忽略父 bean 的 class 属性,让子 bean 指定自己的类,而共享相同的属性配置。但此时 abstract 必须设为 true。
有的时候创建一个 bean 的时候需要保证另外一个 bean 也被创建,这时我们称前面的 bean 对后面的 bean 有依赖。例如:要求创建 Employee 对象的时候必须创建 Department。
这里需要注意的是依赖关系不等于引用关系,Employee 即使依赖 Department 也可以不引用它。
<bean id="emp03" class="com.parent.bean.Employee" depends-on="dept">
<property name="empId" value="1003"/>
<property name="empName" value="Kate"/>
<property name="age" value="21"/>
</bean>
在 Spring 中,可以在元素的 scope 属性里设置 bean 的作用域,以决定这个 bean 是单实例的还是多实例的。
默认情况下,Spring 只为每个在 IOC 容器里声明的 bean 创建唯一一个实例,整个 IOC 容器范围内都能共享该实例:所有后续的 getBean()调用和 bean 引用都将返回这个唯一的 bean 实例。该作用域被称为 singleton,它是所有 bean 的默认作用域。
当 bean 的作用域为单例时,Spring 会在 IOC 容器对象创建时就创建 bean 的对象实例。而当 bean 的作用域为 prototype 时,IOC 容器在获取 bean 的实例时创建 bean 的实例对象。
当 bean 的配置信息逐渐增多时,查找和修改一些 bean 的配置信息就变得愈加困难。这时可以将一部分信息提取到 bean 配置文件的外部,以 properties 格式的属性文件保存起来,同时在 bean 的配置文件中引用 properties 属性文件中的内容,从而实现一部分属性值在发生变化时仅修改 properties 属性文件即可。这种技术多用于连接数据库的基本信息的配置。
直接配置:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="root"/>
<property name="password" value="root"/>
<property name="jdbcUrl" value="jdbc:mysql:127.0.0.1:3306/test"/>
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
</bean>
创建 properties 属性文件
prop.userName=root
prop.password=root
prop.url=jdbc:mysql:127.0.0.1:3306/test
prop.driverClass=com.mysql.jdbc.Driver
从 properties 属性文件中引入属性值
<!-- 指定properties属性文件的位置 →<context:property-placeholder location="classpath:jdbc.properties"/><!-- 从properties属性文件中引入属性值 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${prop.userName}"/>
<property name="password" value="${prop.password}"/>
<property name="jdbcUrl" value="${prop.url}"/>
<property name="driverClass" value="${prop.driverClass}"/>
</bean>
概念
装配模式
简介
Spring Expression Language,Spring 表达式语言,简称 SpEL。支持运行时查询并可以操作对象图。和 JSP 页面上的 EL 表达式一样,SpEL 根据 JavaBean 风格的 getXxx()、setXxx()方法定义的属性访问对象图,完全符合我们熟悉的操作习惯。
基本语法
SpEL 使用#{…}作为定界符,所有在大框号中的字符都将被认为是 SpEL 表达式。
使用字面量
概述
相对于 XML 方式而言,通过注解的方式配置 bean 更加简洁和优雅,而且和 MVC 组件化开发的理念十分契合,是开发中常用的使用方式。
使用注解标识组件
组件被上述注解标识后还需要通过 Spring 进行扫描才能够侦测到。
<!-- 开启注解 -->
<context:annotation-config />
<!-- 配置容器资源扫描的包 -->
<context:component-scan base-package="com.component"/>