一.使用AspectJ 实现AOP
注解方式实现AOP:
- AspectJ是一个基于Java语言的AOP框架;
- Spring2.0以后新增对AspectJ切点表达式支持;
- @AspectJ是AspectJ1.5新增功能,通过JDK1.5注解技术,允许直接在bean中定义切面;
- 新版本Spring框架,建议使用AspectJ方式来开发AOP;
- 使用AspectJ需要导入Spring AOP和AspectJ相关jar包
-
<!--aop基础依赖包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.1.9.RELEASE</version> </dependency> <dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version> </dependency> <!--AspectJ--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>4.1.7.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.13</version> </dependency>
二.目录结构
三.注解开发:环境准备
-
<?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"> <!--开启aspectj注解自动扫描--> <aop:aspectj-autoproxy/> <bean id="productDao" class="com.batac.demo1.ProductDao"/> <!--加载bean--> <bean class="com.batac.demo1.MyAspectAnno"/> </beans>
四.增强类代码
package com.batac.demo1;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
/**
* 切面类
*/
@Aspect
public class MyAspectAnno {
//---------------------------------前置通知---------------------------------
/**
*
*/
// 1.ProductDao中所有的方法都会被增强
// @Before(value = "execution(* com.batac.demo1.ProductDao.*(..))")
// 2.ProductDao中的save方法会被前置增强;
@Before(value = "execution(* com.batac.demo1.ProductDao.save(..))")
public void before(){
System.out.println("前置通知");
}
// 3.ProductDao中的save方法会被前置增强;参数:获取连接点
@Before(value = "execution(* com.batac.demo1.ProductDao.save(..))")
public void before(JoinPoint joinPoint){
System.out.println("前置通知" + joinPoint);
}
//---------------------------------后置通知---------------------------------
@AfterReturning(value = "execution(* com.batac.demo1.ProductDao.delete(..))")
public void afterReturint(){
System.out.println("---后置通知---");
}
// 获取返回数据
@AfterReturning(value = "execution(* com.batac.demo1.ProductDao.delete(..))",returning = "result")
public void afterReturint(Object result){
System.out.println("---后置通知---" + result);
}
//---------------------------------环绕通知---------------------------------
//环绕通知
@Around(value = "execution(* com.batac.demo1.ProductDao.find(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕前");
Object object = (Object) joinPoint.proceed();//执行目标方法
System.out.println("环绕后");
return object;
}
// 异常通知
@AfterThrowing(value = "execution(* com.batac.demo1.ProductDao.find(..))",throwing = "e")
public void afterThrowing(Throwable e){
System.out.println("异常抛出通知:" + e.getMessage());
}
}
五.需要增强的类:
package com.batac.demo1;
public class ProductDao {
public void save(){
System.out.println("save");
}
public String delete(){
System.out.println("delete");
return "Nihao";
}
public void update(){
System.out.println("update");
}
public void find(){
System.out.println("find");
// int a = 10/0;
}
}
六.测试类
package com.batac.demo1;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class ProductDaoTest {
@Resource(name = "productDao")
private ProductDao productDao;
@Test
public void demo1(){
productDao.delete();
productDao.find();
productDao.save();
productDao.update();
}
}