12_Spring_AOP注解方式实现_掌握
12_Spring_AOP注解方式实现_掌握
AspectJ本身并不是spring框架中的组成部分,
是一个独立的AOP框架,一般把AspectJ和Spring框架的AOP依赖一起使用,所以要导入一个独立的依赖
实现的两种方式
1 基于注解方式实现 (熟练)
2 基于XML配置方式 (了解)
准备工作1
导入依赖
-
-
<!--spring核心容器包--> -
<dependency> -
<groupId>org.springframework</groupId> -
<artifactId>spring-context</artifactId> -
<version>5.3.5</version> -
</dependency> -
<!--spring切面包--> -
<dependency> -
<groupId>org.springframework</groupId> -
<artifactId>spring-aspects</artifactId> -
<version>5.3.5</version> -
</dependency> -
<!--织入包 spring-aspects 已经导入该包,这里可以不导入--> -
<!--<dependency> -
<groupId>org.aspectj</groupId> -
<artifactId>aspectjweaver</artifactId> -
<version>1.9.6</version> -
</dependency>--> -
<!--aop联盟包--> -
<dependency> -
<groupId>aopalliance</groupId> -
<artifactId>aopalliance</artifactId> -
<version>1.0</version> -
</dependency> -
<!--Apache Commons日志包--> -
<dependency> -
<groupId>commons-logging</groupId> -
<artifactId>commons-logging</artifactId> -
<version>1.2</version> -
</dependency> -
<!--德鲁伊连接池--> -
<dependency> -
<groupId>com.alibaba</groupId> -
<artifactId>druid</artifactId> -
<version>1.1.10</version> -
</dependency> -
<!--mysql驱动--> -
<dependency> -
<groupId>mysql</groupId> -
<artifactId>mysql-connector-java</artifactId> -
<version>8.0.22</version> -
</dependency> -
<!--Junit单元测试--> -
<dependency> -
<groupId>junit</groupId> -
<artifactId>junit</artifactId> -
<version>4.13.1</version> -
<scope>test</scope> -
</dependency> -
<!--lombok --> -
<dependency> -
<groupId>org.projectlombok</groupId> -
<artifactId>lombok</artifactId> -
<version>1.18.12</version> -
<scope>provided</scope> -
</dependency> -
</dependencies>
准备工作2
切入点表达式: 通过一个表达式来确定AOP要增强的是哪个或者那些方法
语法结构:execution([权限修饰符][返回值类型][类的全路径名][方法名](参数 列表) )
例子1
execution(* com.msb.dao.UserDaoImpl.add(..)) //指定切点为UserDaoImpl.add方法
execution(* com.msb.dao.UserDaoImpl.*(..)) //指定切点为UserDaoImpl.所有的方法
execution(* com.msb.dao..(..))
//指定切点为dao包下所有的类中的所有的方法
execution(* com.msb.dao.*.add(..)) //
指定切点为dao包下所有的类中的add的方法
execution(* com.msb.dao..add(..)) //
指定切点为dao包下所有的类中的add开头的方法
基于注解方式实现
项目结构
开启注解扫描和AOP切面编程自动生成代理对象配置
- <beans xmlns="http://www.springframework.org/schema/beans"
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" -
xmlns:p="http://www.springframework.org/schema/p" -
xmlns:c="http://www.springframework.org/schema/c" -
xmlns:util="http://www.springframework.org/schema/util" -
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/util -
http://www.springframework.org/schema/util/spring-util.xsd -
http://www.springframework.org/schema/context -
http://www.springframework.org/schema/context/spring-context.xsd -
http://www.springframework.org/schema/aop -
http://www.springframework.org/schema/aop/spring-aop.xsd - ">
-
<!--spring 包扫描 --> -
<context:component-scan base-package="com.msb"/> -
<!--aop autoProxy 自动生成代理对象 --> -
<aop:aspectj-autoproxy/>
准备接口
UserDao和EmpDao
-
package com.msb.dao;
-
/**
-
- @Author: Ma HaiYang
-
- @Description: MircoMessage:Mark_7001
-
*/
-
public interface EmpDao {
-
int addEmp(Integer empno,String ename,String job); -
}
-
package com.msb.dao;
-
/**
-
- @Author: Ma HaiYang
-
- @Description: MircoMessage:Mark_7001
-
*/
-
public interface UserDao {
-
int addUser(Integer userid,String username); -
}
接口实现类
-
package com.msb.dao.impl;
-
import com.msb.dao.UserDao;
-
import org.springframework.stereotype.Repository;
-
/**
-
- @Author: Ma HaiYang
-
- @Description: MircoMessage:Mark_7001
-
*/
-
@Repository
-
public class UserDaoImpl implements UserDao {
-
public int addUser(Integer userid,String username){ -
System.out.println("userdao add ... ..."); -
//int i =1/0; -
return 1; -
} -
}
-
package com.msb.dao.impl;
-
import com.msb.dao.EmpDao;
-
import com.msb.dao.UserDao;
-
import org.springframework.stereotype.Repository;
-
/**
-
- @Author: Ma HaiYang
-
- @Description: MircoMessage:Mark_7001
-
*/
-
@Repository
-
public class EmpDaoImpl implements EmpDao {
-
public int addEmp(Integer empno,String ename,String job){ -
System.out.println("empDao add ... ..."); -
return 1; -
} -
}
准备切面
- package com.msb.aspect;
- import org.aspectj.lang.JoinPoint;
- import org.aspectj.lang.ProceedingJoinPoint;
- import org.aspectj.lang.annotation.*;
- import org.springframework.core.annotation.Order;
- import org.springframework.stereotype.Component;
- import java.util.Arrays;
- /**
-
- @Author: Ma HaiYang
-
- @Description: MircoMessage:Mark_7001
- */
- @Component
- @Aspect
- public class DaoAspect {
-
//定义公共切点 -
@Pointcut("execution(* com.msb.dao.*.add*(..))") -
public void addPointCut(){} -
/* -
* 前置通知: 切点方法执行之前先执行的功能 -
* 参数列表可以用JoinPoint接收切点对象 -
* 可以获取方法执行的参数 -
* */ -
@Before("addPointCut()") -
public void methodBefore(JoinPoint joinPoint){ -
System.out.println("Before invoked"); -
} -
/* -
* 后置通知:方法执行之后要增强的功能 -
* 无论切点方法是否出现异常都会执行的方法 -
* 参数列表可以用JoinPoint接收切点对象 -
* */ -
@After("addPointCut()") -
public void methodAfter(JoinPoint joinPoint){ -
System.out.println("After invoked"); -
} -
/* -
* 返回通知:切点方法正常运行结束后增强的功能 -
* 如果方法运行过程中出现异常,则该功能不运行 -
* 参数列表可以用 JoinPoint joinPoint接收切点对象 -
* 可以用Object res接收方法返回值,需要用returning指定返回值名称 -
* */ -
@AfterReturning( value = "addPointCut()",returning = "res") -
public void methodAfterReturning(JoinPoint joinPoint,Object res){ -
System.out.println("AfterReturning invoked"); -
} -
/* -
* 异常通知:切点方法出现异常时运行的增强功能 -
* 如果方法运行没有出现异常,则该功能不运行 -
* 参数列表可以用Exception ex接收异常对象 需要通过throwing指定异常名称 -
* */ -
@AfterThrowing( value = "addPointCut()",throwing = "ex") -
public void methodAfterThrowing(Exception ex){ -
System.out.println("AfterThrowing invoked"); -
} -
/*环绕通知:在切点方法之前和之后都进行功能的增强 -
* 需要在通知中定义方法执行的位置,并在执行位置之前和之后自定义增强的功能 -
* 方法列表可以通过ProceedingJoinPoint获取执行的切点 -
* 通过proceedingJoinPoint.proceed()方法控制切点方法的执行位置 -
* proceedingJoinPoint.proceed()方法会将切点方法的返回值获取到,并交给我们,可以做后续处理 -
* 我们在环绕通知的最后需要将切点方法的返回值继续向上返回,否则切点方法在执行时接收不到返回值 -
* */ -
@Around("addPointCut()") -
throws Throwable {public Object methodAround(ProceedingJoinPoint proceedingJoinPoint) -
System.out.println("aroundA invoked"); -
Object proceed = proceedingJoinPoint.proceed(); -
System.out.println("aroundB invoked"); -
return proceed; -
} - }
测试代码
-
@Test -
public void test1(){ -
ClassPathXmlApplicationContext("applicationContext.xml");ApplicationContext context=new -
UserDao userDao = context.getBean( UserDao.class); -
int add = userDao.addUser(10,"晓明"); -
}
有多个增强类对同一个方法进行增强,通过@Order注解设置增强类优先级
数字越小,优先级越高
数字越小,其代理位置越靠近注入位置
完全使用注解开发
创建配置类
- package com.msb.config;
- import org.springframework.context.annotation.ComponentScan;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.context.annotation.EnableAspectJAutoProxy;
- /**
-
- @Author: Ma HaiYang
-
- @Description: MircoMessage:Mark_7001
- */
- @Configuration
- @ComponentScan(basePackages = "com.msb")
- @EnableAspectJAutoProxy(proxyTargetClass = true)
- public class SpringConfig {
- }
测试代码
-
@Test -
public void test2(){ -
AnnotationConfigApplicationContext(SpringConfig.class);ApplicationContext context=new -
UserDao userDao = context.getBean( UserDao.class); -
int add = userDao.addUser(10,"晓明"); -
}
Generated with Mybase Desktop 8.2.13

浙公网安备 33010602011771号