IoC和AOP使用扩展
多种方式实现依赖注入
构造注入
如何通过构造注入为业务类注入所依赖的数据访问层对象,实现保存用户数据的功能?
解决问题的步骤如下:
- 获取Spring开发包并为工程添加Spring支持。
- 为业务层和数据访问层设计接口,声明所需方法。
- 编写数据访问层接口UserDao的实现类,完成具体的持久化操作。
- 在业务实现类中声明UserDao接口类型的属性,并添加适当的构造方法为属性赋值。
- 在Spring的配置文件中将DAO对象以构造注入方式赋值给业务实例中的UserDao类型的属性。
- 在代码中获取Sping配置文件中装配好的业务类对象,实现程序功能。
在业务实现类中声明UserDao接口类型的属性,并添加构造方法的关键代码如下:
/**
* 用户业务类,实现对User功能的业务管理
*/
public class UserServiceImpl implements UserService {
// 声明接口类型的引用,和具体实现类解耦合
private UserDao dao;
// 无参构造
public UserServiceImpl() {
}
// 用于为dao属性赋值的构造方法
public UserServiceImpl(UserDao dao) {
this.dao = dao;
}
public void addNewUser(User user) {
// 调用用户DAO的方法保存用户信息
dao.save(user);
}
}
使用设值注入时,Spring通过JavaBean的无参构造方法实例化对象。当我们编写带参构造方法后,Java虚拟机不会再提供默认的无参构造方法。为了保证使用的灵活性,建议自行添加一个无参构造方法。
在Spring的配置文件中将DAO对象以构造注入的方式赋值给业务类对象相关属性的关键代码如下
<?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.2.xsd ">
<!-- 定义UserDaoImpl对象,并指定id为userDao -->
<bean id="userDao" class="dao.impl.UserDaoImpl" />
<!-- 定义UserServiceImpl对象,并指定id为userService -->
<bean id="userService" class="service.impl.UserServiceImpl">
<!-- 通过定义的单参构造为userService的dao属性赋 值 -->
<constructor-arg>
<!-- 引用id为userDao的对象为userService的dao属性赋值 -->
<ref bean="userDao" />
</constructor-arg>
</bean>
</beans>
(1) 一个元素表示构造方法的一个参数,且使用时不区分顺序。 物方法的参数出现混淆,无法区分时,可以通过元素 的index属性指宝-参教的位置索引,位置从0开始。 元素还提供了type属性用来指定参数的类型,避免字符串和基本数据类型的混淆。
(2)构造注入的时效性好,在对象实例化时就得到所依赖的对象,便于在对象的初始化方法中使用依赖对象;但受限于方法重载的形式,使用灵活性不足。设值注入使用灵活、但时效性不足,并且大量的setter访问器增加了类的复杂性。Spring 并不倾向于某种注入方式,用户应该根据实际情况进行合理的选择。
当然Spring提供的注入方式不只这两种,只是这两种方式用得最普遍,有兴趣的学员可以通过Spring的开发手册了解其他注入方式。
使用p命名空间实现属性注入
Spring配置文件从2.0版本开始采用schema形式,使用不同的命名空间管理不同类型的配置使得配置文件更具扩展性。例如,我们曾使用aop命名空间下的标签实现织入切面的功能,而在本章及之后章节的学习中,我们还会接触更多其他命名空间下的配置。此外, Spring基于schema的配置方案为许多领域的问题提供了简化的配置方法,大大简化了配置的工作量。在本节中,我们,。
验使用p命名空间简化属性的注入。
注入不同数据类型
Spring 提供了不同的标签来实现各种不同类型参数的注入,这些标签对于设值注入和构造注入都适用。在本节中,将以设值注入的形式介绍,对于构造注入,只需将所介绍的标签添加到constructio-arg标签中即可。
其他增强类型
Spring 支持多种增强类型,除了之前介绍过的前置增强和后置增强,这里在补充介绍几种常见的增强类型。
异常抛出增强
异常抛出增强的特点是在目标方法抛出异常时织入的增强处理。使用异常抛出增强,可以为各功能模块提供统一的,可拔插的异常处理方案。
最终增强
环绕增强
使用注解实现IoC的配置
前面我们学习了多种Spring IoC有关的配置技巧,这些技巧都是基于XML形式的配置文件进行的。处理XML形式的配置文件,Spring从2.0版本开始引入了注解的配置方式,将Bean的配置信息和Bean实现类结合在一起,进一步减少了配置文件的代码量。
使用注解定义Bean
使用注解实现Bean组件装配
加载注解定义的Bean
使用Java标准注解完成装配
使用注解定义切面
AspectJ简介
AspectJ是一个面向切面的框架,他扩展了Java语言,定义了AOP语法,能够在编译期提供代码的织入,所以它有一个专门的编译器用来生成遵守字节编码规范的Class文件。
@AspectJ是AspectJ 5新增的功能,使用JDK 5.0注解技术和正规的AspectJ切点表达式语言描述切面。因此在使用@AspectJ之前,需要保证所使用的JDK是5.0或以上的版本,否则无法使用注解技术。
Spring通过集成AspectJ实现了以注解的方式定义切面,大大减少了配置文件的工作量。此外,因为Java的反射机制无法获取方法参数名,Spring还需要利用轻量级的字节码处理框架asm(已集成在Spring Core 模块中)处理@AspectJ中所描述的方法参数名。
使用注解标注切面
使用注解定义其他类型的增强