基于xml配置的aop实现以及例子
<aop:around>
, <aop:aspect>
元素的子元素,属性method指定环绕通知方法,属性pointcut-ref指定关联的切入点。<aop:before>
, 属性method指定前置通知方法,属性pointcut-ref指定关联的切入点。<aop:after-returning>
, 属性method指定后置返回通知方法,属性pointcut-ref指定关联的切入点。<aop:after>
, 属性method指定后置(最终)通知,属性pointcut-ref指定关联的切入点。<aop:after-throwing>
, 属性method指定异常通知 ,属性pointcut-ref指定关联的切入点。<aop:declare-parents>
, 给通知引入新的额外接口,增强功能。(不要求掌握)Spring-aspects-5.0.2.release.jar
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
aspectjweaver-1.8.13.jar
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<!-- <scope>test</scope>-->
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
MyAspect.java
package cn.lacknb.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
/*
* 切面类
* 在此类中编写各种类型的通知
* */
public class MyAspect {
/*
* 前置通知,使用JoinPonit接口作为参数获得目标对象信息
*
* */
public void before(JoinPoint jp){
System.out.println("前置通知:模拟权限控制");
System.out.println(",目标对象:" + jp.getTarget()
+ ",被增强处理的方法:" + jp.getSignature().getName());
}
/*
* 后置返回通知
*
* */
public void afterReturning(JoinPoint jp){
System.out.println("后置返回通知:" + "模拟删除临时文件");
System.out.println(",被增强处理的方法: " + jp.getSignature().getName());
}
/*
* 环绕通知
* ProceedingJoinPoint是JoinPoint的子接口,代表可以执行的目标方法
* 返回值的类型必须是Object
* 必须一个参数是ProceedingJoinPoint类型
* 必须throws Throwable
* */
public Object around(ProceedingJoinPoint pjp) throws Throwable{
// 开始
System.out.println("环绕开始:执行目标在前,模拟开启事务");
// 执行当前目标方法
Object obj = pjp.proceed();
// 结束
System.out.println("环绕结束:执行目标方法后,模拟关闭事务");
return obj;
}
/*
* 异常通知
* */
public void except(Throwable e){
System.out.println("异常通知:" + "程序执行异常" + e.getMessage());
}
/*
* 后置最终通知
* */
public void after(){
System.out.println("最终通知:模拟释放资源");
}
}
TestDao.java
package cn.lacknb.dao;
public interface TestDao {
public void save();
public void modify();
public void delete();
}
TestDaoImpl.java
package cn.lacknb.dao;
public class TestDaoImpl implements TestDao {
public void save(){
System.out.println("保存");
}
public void modify(){
System.out.println("修改");
}
public void delete(){
System.out.println("删除");
}
}
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: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
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- bean definitions here -->
<!-- 定义目标对象 -->
<bean id="testDao" class="cn.lacknb.dao.TestDaoImpl"/>
<!-- 定义切面 -->
<bean id="myAspect" class="cn.lacknb.aspect.MyAspect"/>
<!-- aop配置 -->
<aop:config>
<!-- 配置切面 -->
<aop:aspect ref="myAspect">
<!-- 配置切入点,通知增强哪些方法 -->
<aop:pointcut expression="execution(* cn.lacknb.dao.*.*(..))" id="myPointcut"/>
<!-- 将通知于切入点关联 -->
<!-- 关联前置通知 -->
<aop:before method="before" pointcut-ref="myPointcut"/>
</aop:aspect>
</aop:config>
</beans>
MyTest.java
package cn.lacknb.test;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.lacknb.dao.TestDao;
public class MyTest {
ApplicationContext context = null;
@Before
public void init(){
context = new ClassPathXmlApplicationContext("applicationContext.xml");
}
@Test
public void test01(){
TestDao test = (TestDao) context.getBean("testDao");
test.save();
test.delete();
test.modify();
}
}
xml文件
<!-- 关联后置返回通知,在目标方法成功执行后执行 -->
<aop:after-returning method="afterReturning" pointcut-ref="myPointcut"/>
xml文件
<!-- 关联环绕通知 -->
<aop:around method="around" pointcut-ref="myPointcut"/>
结果
xml文件
<!-- 关联异常通知,没有异常发生时将不会执行增强, throwing属性设置通知的第二个参数的名称 -->
<aop:after-throwing method="except" pointcut-ref="myPointcut" throwing="e"/>
xml文件
<!-- 关联后置最终通知, 不管目标方法是否成功都要执行 -->
<aop:after method="after" pointcut-ref="myPointcut"/>
结果