1.什么是AOP?
AOP面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
2.为什么使用AOP?
1.分离系统中的各种关注点,将核心关注点和横切关注点分离开来。
2.减少代码的重复,各个模块的重用性加强。
3.降低 模块间的耦合度,提高代码的可操作性和可维护性。
3..AOP应用场景
1.记录日志
2.权限校验
3.spring事务管理
4.AOP的结构
AOP要做的三件事在哪里切入,也就是权限校验,等非业务操作在哪些业务 代码中执行;什么时候切入,是业务代码执行前还是执行后;切入后做什 么事,比如做权限校验、日志记录等。
5.如何使用AOP
1.先要引入依赖
<!--spring 核心依赖库--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.15.RELEASE</version> </dependency> <dependency> <!--aop 切面依赖--> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.2.15.RELEASE</version> </dependency>
2.spring.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: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/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!--包扫描--> <context:component-scan base-package="com.math"/> <!--开启aop 面向切面--> <aop:aspectj-autoproxy/> <!-- <aop:aspectj-auoproxy/>--> </beans>
public interface MathService {
/**
* 加法运算
* @param a
* @param b
* @return
*/
public double add(double a,double b);
/**
* 减法运算
* @param a
* @param b
* @return
*/
public double mul(double a,double b
@Service
public class MathServiceImpl implements MathService {
public double add(double a, double b) {
double result=a+b;
return result;
}
public double mul(double a, double b) {
double result=a-b;
return result;
}
}
@Aspect//标记该类为切面类
@Component
public class Math {
/**
* 使用通配符 *
* 第一个* 代表 任意修饰符 任意返回值
* 第二个* 代表 这个包下的 所有类
* 第三个* 代表 类下的所有方法
* . . 代表 任意参数
*/
@Pointcut(value = "execution(* com.math.*.*(..))")//定义切点
public void mypointcut(){}
@After(value = "mypointcut()") //后置处理 无论什么情况 都执行
public void a(){
System.out.println("后置切面aop-----");
}
3.测试
public class test {
public static void main(String[] args) {
// 加载spring 配置文件
ApplicationContext app=new ClassPathXmlApplicationContext("classpath:spring.xml");
MathService mathService = (MathService) app.getBean("mathServiceImpl");
System.out.println(mathService.mul(20,10));
}
}
5.2注解模式
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AopAnnotation {
String value() default "";
}
@AopAnnotation
@Service
public class MathServiceImpl implements MathService {
@AopAnnotation
public double add(double a, double b) {
double result=a+b;
return result;
}
@AopAnnotation
public double mul(double a, double b) {
double result=a-b;
return result;
}
}
@Aspect//标记该类为切面类
@Component
public class Math {
//使用注解
@Pointcut(value = "@annotation(com.math.annotation.AopAnnotation)")// 切点
public void mypointcut2(){}
@After(value = "mypointcut()") //后置处理 无论什么情况 都执行
public void a(){
System.out.println("后置切面aop-----");
5.3AOP切面通知的类型
@Before:前置通知 执行前 通知
@Aftter:后置处理 执行完通知
@AfterReturning:后置返回通知 returning =“ ”会把执行的结果 赋值给变量
@AfterThrowing:异常通知 出异常时候通知
@Around:环绕通知 joinPoint 连接点
@After(value = "mypointcut()") //后置处理 无论什么情况 都执行 public void a(){ System.out.println("后置切面aop-----"); } @Before(value = "mypointcut()")//前置处理 在运行前执行 public void b(){ System.out.println("前置切面aop--------"); } @AfterReturning(value="mypointcut()",returning="r")//后置返回通知 returning 会把执行的结果 赋值给变量 public void returning(Object r){ System.out.println("后置返回切面aop---------"+r); } @AfterThrowing(value = "mypointcut()")//异常处理 只有出异常才会执行 public void throwing(){ System.out.println(" 出异常时切面aop-----------"); }
@Around(value = "mypointcut2( )")//环绕出里 public Object around(ProceedingJoinPoint joinPoint){//joinPoint 连接点理解为被执行的方法对象 System.out.println("业务代码执行前的内容---------"); try { Object reuslt=joinPoint.proceed();// 执行你的连接点 int i=10/0; System.out.println("方法执行完毕后---------"); return reuslt; } catch (Throwable e) { e.printStackTrace(); System.out.println("方法出异常时执行--------"); }finally { System.out.println("无论如何都会执行"); } return null; }