1、XML配置相关元素
我们知道注解很方便,并且是很强大的东西,并且在平时的开发中基本都会使用注解开发,但基于 XML 的方式我们仍然需要了解,其实就跟注解差不多的功能,只是换了一种形式,下面先来了解一下 AOP 中可以配置的元素:
AOP 配置元素 | 用途 |
---|---|
aop:advisor |
定义 AOP 的通知其(一种很古老的方式,很少使用) |
aop:aspect |
定义一个切面 |
aop:before |
定义前置通知 |
aop:after |
定义后置通知 |
aop:around |
定义环绕通知 |
aop:after-returning |
定义返回通知 |
aop:after-throwing |
定义异常通知 |
aop:config |
顶层的 AOP 配置元素。大多数的<aop:*>元素必须包含在<aop:config>中 |
aop:declare-parents |
给通知引入新的额外接口,增强功能 |
aop:pointcut |
定义切点 |
2、基于XML配置AOP
[1]、配置applicationContext.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 将被代理的目标类加入IOC容器 -->
<bean class="com.thr.aop.target.UserServiceImpl" id="userService"/>
<!-- 将切面类加入IOC容器 -->
<bean class="com.thr.aop.aspect.LogXmlAspect" id="logXmlAspect"/>
<!-- 配置AOP -->
<aop:config>
<!-- 声明切入点表达式 -->
<aop:pointcut id="logPointCut" expression="execution(* *..*.*(..))"/>
<!-- 配置切面,使用ref属性引用切面类对应的bean。如有需要可以使用order属性指定当前切面的优先级数值 -->
<aop:aspect ref="logXmlAspect">
<!-- 配置具体通知方法,通过pointcut-ref属性引用上面已声明的切入点表达式 -->
<aop:before method="doBefore" pointcut-ref="logPointCut"/>
<!-- 在返回通知中使用returning属性指定接收方法返回值的变量名 -->
<aop:after-returning method="doAfterReturning" pointcut-ref="logPointCut" returning="returnValue"/>
<!-- 在异常通知中使用throwing属性指定接收异常对象的变量名 -->
<aop:after-throwing method="doAfterThrowing" pointcut-ref="logPointCut" throwing="throwable"/>
<!-- 配置后置帖子 -->
<aop:after method="doAfter" pointcut-ref="logPointCut"/>
</aop:aspect>
</aop:config>
</beans>
[2]、创建目标接口
/**
* 目标类接口
*/
public interface IUserService {
void addUser(String userName,Integer age);
}
[3]、创建目标接口实现类
/**
* 目标类,会被动态代理
*/
@Service
public class UserServiceImpl implements IUserService {
@Override
public void addUser(String userName, Integer age) {
System.out.println(userName + ":" + age);
}
}
[4]、创建切面类
/**
* 创建日志切面类
*/
public class LogXmlAspect {
public void doBefore(JoinPoint joinPoint) { // 在通知方法中,声明JoinPoint类型的形参,就可以在Spring调用当前方法时把这个类型的对象传入
// 1.通过JoinPoint对象获取目标方法的签名
// 所谓方法的签名就是指方法声明时指定的相关信息,包括方法名、方法所在类等等
Signature signature = joinPoint.getSignature();
// 2.通过方法签名对象可以获取方法名
String methodName = signature.getName();
// 3.通过JoinPoint对象获取目标方法被调用时传入的参数
Object[] args = joinPoint.getArgs();
// 4.为了方便展示参数数据,把参数从数组类型转换为List集合
List<Object> argList = Arrays.asList(args);
System.out.println("[前置通知]" + methodName + "方法开始执行,参数列表是:" + argList);
}
public void doAfterReturning(JoinPoint joinPoint, Object returnValue) {
String methodName = joinPoint.getSignature().getName();
System.out.println("[返回通知]" + methodName + "方法成功结束,返回值是:" + returnValue);
}
public void doAfterThrowing(JoinPoint joinPoint, Throwable throwable) {
String methodName = joinPoint.getSignature().getName();
System.out.println("[异常通知]" + methodName + "方法异常结束,异常信息是:" + throwable.getMessage());
}
public void doAfter(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
System.out.println("[后置通知]" + methodName + "方法最终结束");
}
}
[5]、创建测试类
public class XmlAOPTest {
//创建ApplicationContext对象
private ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
@Test
public void testAOP(){
// 1.从IOC容器中获取接口类型的对象
IUserService userService = ac.getBean(IUserService.class);
// 2.调用方法查看是否应用了切面中的通知
userService.addUser("张三",20);
}
}
[6]、运行结果