外部属性文件使用
通过 ${var} 的方式在XML文件中进行引用外部属性文件的内容。
Spring 还允许在属性文件中使用 ${propName},以实现属性之间的相互引用。
Spring 2.0:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:db.properties"></property>
</bean>
Spring 2.5 之后:
<context:property-placeholder location="classpath:db.properties"/>
Spring表达式语言:SpEL
是一个支持运行时查询和操作对象图的强大的表达式语言。
SpEL 使用 #{…} 作为定界符,所有在大框号中的字符都将被认为是 SpEL。
字面量的表示:
整数:<property name="count" value="#{5}"/>
小数:<property name="frequency" value="#{89.7}"/>
科学计数法:<property name="capacity" value="#{1e4}"/>
String可以使用单引号或者双引号作为字符串的定界符号:<property name=“name” value="#{'Chuck'}"/> 或 <property name='name' value='#{"Chuck"}'/>
Boolean:<property name="enabled" value="#{false}"/>
SpEL:引用 Bean、属性和方法
引用其它对象:
<!--通过value属性和SpEL配置Bean之间的应用关系-->
<property name="prefix" value="#{prefixGenerator}"></property>
引用其它对象的属性:
<!--通过value属性和SpEL 进行对象属性赋值-->
<property name="suffix" value="#{prefixGenerator.suffix}"></property>
调用其它对象方法:
<!--通过value属性和SpEL 进行对象方法返回结果赋值-->
<property name="suffix" value="#{prefixGenerator.toString()}"></property>
<!--方法连缀-->
<property name="suffix" value="#{prefixGenerator.toString().toUpperCase()}"></property>
调用静态方法静态属性:
<property name="suffix" value="#{T(java.lang.Math).PI}"></property>
SpEL支持的运算符号:
算术运算符:+,-,*,/,%,^(加号还可以用作字符串连接)
比较运算符:< , > , == , >= , <= , lt , gt , eg , le , ge
逻辑运算符:and , or , not , |
if-else 运算符(类似三目运算符):?:(temary), ?:(Elvis)
正则表达式:#{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}'}
IOC 容器中 Bean 的生命周期
Spring IOC 容器对 Bean 的生命周期进行管理的过程:
1 通过构造器或工厂方法创建 Bean 实例
2 为 Bean 的属性设置值和对其他 Bean 的引用
3 调用 Bean 的初始化方法(init-method)
4 Bean 可以使用了
5 当容器关闭时, 调用 Bean 的销毁方法(destroy-method)
Bean 后置处理器
Bean 后置处理器允许在调用初始化方法前后对 Bean 进行额外的处理.
Bean 后置处理器对 IOC 容器里的所有 Bean 实例逐一处理, 而非单一实例.
public interface BeanPostProcessor {
//对象初始化之前处理
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
//对象初始化之后处理
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
添加 Bean 后置处理器后 Bean 的生命周期:
1通过构造器或工厂方法创建 Bean 实例
2为 Bean 的属性设置值
3将 Bean 实例传递给 Bean 后置处理器的 postProcessBeforeInitialization 方法
4调用 Bean 的初始化方法
5将 Bean 实例传递给 Bean 后置处理器的 postProcessAfterInitialization方法
6 Bean 使用
7 当容器关闭时, 调用 Bean 的销毁方法
classpath 组件扫描
通过配置<context:component-scan> Spring 能够从 classpath 下自动扫描, 侦测和实例化具有特定注解的组件.
特定组件包括:
@Component: 基本注解, 标识了一个受 Spring 管理的组件
@Respository: 标识持久层组件
@Service: 标识服务层(业务层)组件
@Controller: 标识表现层组件
注意:Spring 有默认的命名策略: 使用非限定类名, 第一个字母小写. 也可以在注解中通过 value 属性值标识组件的名称
base-package属性
指定一个需要扫描的基类包,Spring 容器将会扫描这个基类包里及其子包中的所有类.
当需要扫描多个包时, 可以使用逗号分隔.
resource-pattern属性
可以使用过滤特定的类.
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.spring.aop"></context:component-scan>
<context:include-filter> 子节点表示要包含的目标类。(可以多个)
<context:exclude-filter> 子节点表示要排除在外的目标类。(可以多个)
多种类型的过滤表达式:
组件装配
<context:component-scan> 元素还会自动注册 AutowiredAnnotationBeanPostProcessor 实例, 该实例可以自动装配具有 @Autowired 和 @Resource 、@Inject注解的属性.
@Autowired
1 构造器, 普通字段(即使是非 public), 一切具有参数的方法都可以应用@Authwired 注解
2 通过属性类型查找对应bean
3若某一属性允许不被设置, 可以设置 @Authwired 注解的 required 属性为 false
4 @Qualifier 注解里提供 Bean 的名称
5 @Authwired 注解也可以应用在数组类型的属性上, 此时 Spring 将会把所有匹配的 Bean 进行自动装配.
6 @Authwired 注解也可以应用在集合属性上, 此时 Spring 读取该集合的类型信息, 然后自动装配所有与之兼容的 Bean.
7 @Authwired 注解用在 java.util.Map 上时, 若该 Map 的键值为 String, 那么 Spring 将自动装配与之 Map 值类型兼容的 Bean, 此时 Bean 的名称作为键值
实例一:
public class BookService {
@Autowired
private BookDao bookDao;
}
实例二:
public class BookService {
@Autowired(required=false)
private BookDao bookDao;
}
实例三:
public class BookService {
@Autowired(required=false)
@Qualifier("bookDao")
private BookDao bookDao;
}
@Resource
要求提供一个 Bean 名称的属性,若该属性为空,则自动采用标注处的变量或方法名作为 Bean 的名称
实例:
public class BookService {
@Resource(name="bookDao2")
private BookDao bookDao;
}
@Inject
和 @Autowired 注解一样也是按类型匹配注入的 Bean, 但没有 reqired 属性
泛型依赖注入
Spring 4.x 中可以为子类注入子类对应的泛型类型的成员变量的引用
public class BaseRespository<T> {
public void save(T entity){
System.out.println("Save:" + entity);
}
}
@Repository
public class UserRespository extends BaseRespository<User>{
}
public class BaseService<T> {
@Autowired
private BaseDao<T> dao;
public void addNew(T entity){
System.out.println("addNew by " + dao);
dao.save(entity);
}
}
//若注解没有指定 bean 的 id, 则类名第一个字母小写即为 bean 的 id
@Service
public class UserService extends BaseService<User>{
}
整合多个配置文件
import 元素的 resource 属性