一.上篇文章讲述了通过实现各自的接口来实现aop的通知功能,
二.这次我们通过xml的配置来实现aop。
第二种方法: 使用 AspectJ 开发 AOP – XML
Spring AOP 需要包:
spring-aop-5.2.2.RELEASE.jar
ApectJ开发需要包:
spring-aop-5.2.2.RELEASE.jar
spring-aspects-5.2.2.RELEASE.jar
com.springsource.org.aspectj.weaver-1.7.2.RELEASE.jar
(https://repo.spring.io/webapp/#/search/quick/)
需要的jar包:
持久层:
package com.aop;
public interface UserDao {
public void addUser(String id, String name);
}
实现类:
package com.aop;
public class UserDaoImpl implements UserDao {
@Override
public void addUser(String id, String name) {
// TODO Auto-generated method stub
//String uid=null;
//uid.charAt(0);
System.out.println("===============执行方法逻辑");
}
}
切面类(代理类):
Joinpoint(连接点) |
应用程序执行过程中插入切面的点,是对象操作过程中的某个阶段点。 |
JoinPoint 就是目标对象的一些信息。这里等同于代理userDao类
package com.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class LogAspect {
//前置通知
public void myBefore(JoinPoint joinpoit) {
System.out.println("---前置通知:目标对象:"+joinpoit.getTarget()+"--方法:"+joinpoit.getSignature().getName());
}
//后置通知
public void myAfterReturning(JoinPoint joinpoit) {
System.out.println("---后置通知:目标对象:"+joinpoit.getTarget()+"--方法:"+joinpoit.getSignature().getName());
}
//环绕通知
public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
System.out.println("---环绕通知开始:目标对象:"+proceedingJoinPoint.getTarget()+"--方法:"+proceedingJoinPoint.getSignature().getName());
Object obj = proceedingJoinPoint.proceed();
System.out.println("---环绕通知结束:目标对象:"+proceedingJoinPoint.getTarget()+"--方法:"+proceedingJoinPoint.getSignature().getName());
return obj;
}
//异常通知
public void myAfterThrowing(JoinPoint joinpoit, Throwable e) {
System.out.println("---异常通知:"+e.getMessage());
}
//最终通知
public void myAfter(JoinPoint joinpoit) {
System.out.println("---最终通知:目标对象:"+joinpoit.getTarget()+"--方法:"+joinpoit.getSignature().getName());
}
}
只需要在xml中进行配置userDao和切面的关系即可。最重要的是xml配置
需要引入:
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
即可使用aop的标签!
<!-- 配置切入点 -->
<aop:pointcut expression="execution(* com.aop.UserDao.addUser(..))" id="myPointCut"/>
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- 目标对象 -->
<bean id="userDao" class="com.aop.UserDaoImpl"/>
<!-- 切面 -->
<bean id="logAspect" class="com.aop.LogAspect"/>
<aop:config>
<aop:aspect ref="logAspect">
<!-- 配置切入点 -->
<aop:pointcut expression="execution(* com.aop.UserDao.addUser(..))" id="myPointCut"/>
<!-- 前置通知 -->
<aop:before method="myBefore" pointcut-ref="myPointCut"/>
<!-- after returning通知 -->
<aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut"/>
<!-- 环绕通知 -->
<aop:around method="myAround" pointcut-ref="myPointCut"/>
<!-- after通知 -->
<aop:after method="myAfter" pointcut-ref="myPointCut"/>
<!-- 异常通知 -->
<aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointCut" throwing="e"/>
</aop:aspect>
</aop:config>
</beans>
解释下配置文件的意思:
1.通过expression , expression="execution(* com.aop.UserDao.addUser(..)) 和 userDao中的addUser方法建立了连接,id="myPointCut" 表示把这个方法当成切入点。
2.通过aop:before 表示前置通知, method="myBefore" 表示和切面类中的myBefore()方法建立连接, 切入点是pointcut-ref="myPointCut" ,也就是 把myBefore切入到userDao中的addUser方法中。
然后进行测试:
package com.aop;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
class TestUserDao {
@Test
void testAddUser() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = context.getBean("userDao", UserDao.class);
userDao.addUser("zhm", "zqw");
}
}
测试结果: