12_Spring_AOP注解方式实现_掌握
12_Spring_AOP注解方式实现_掌握
AspectJ本身并不是spring框架中的组成部分,
是一个独立的AOP框架,一般把AspectJ和Spring框架的AOP依赖一起使用,所以要导入一个独立的依赖
实现的两种方式
1 基于注解方式实现 (熟练)
2 基于XML配置方式 (了解)
准备工作1
导入依赖
-
org.springframework spring-context 5.3.5 org.springframework spring-aspects 5.3.5 - <!--
org.aspectj aspectjweaver 1.9.6 - -->
aopalliance aopalliance 1.0 commons-logging commons-logging 1.2 com.alibaba druid 1.1.10 mysql mysql-connector-java 8.0.22 junit junit 4.13.1 test org.projectlombok lombok 1.18.12 provided
准备工作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
- ">
- <context:component-scan base-package="com.msb"/>
- 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()")
- public Object methodAround(ProceedingJoinPoint proceedingJoinPoint)
throws Throwable { - System.out.println("aroundA invoked");
- Object proceed = proceedingJoinPoint.proceed();
- System.out.println("aroundB invoked");
- return proceed;
- }
- }
测试代码
- @Test
- public void test1(){
- ApplicationContext context=new
ClassPathXmlApplicationContext("applicationContext.xml"); - 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(){
- ApplicationContext context=new
AnnotationConfigApplicationContext(SpringConfig.class); - UserDao userDao = context.getBean( UserDao.class);
- int add = userDao.addUser(10,"晓明");
- }
Generated with Mybase Desktop 8.2.13

浙公网安备 33010602011771号