AOP基本概念
1、什么是AOP
(1)面向切面(方面 )编程,通俗描述就是不通过修改源代码的方式在主干功能里面添加新的功能
2、AOP(底层原理)
1、AOP底层使用动态代理
(1)有两种情况
第一种 :有接口情况,使用JDK动态代理![在这里插入图片描述](https://img-blog.csdnimg.cn/ed3890280cbe4a5a8f8591bacc050fbd.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAYWxpdmVsaWZl,size_20,color_FFFFFF,t_70,g_se,x_16)
第二种:没有接口情况,使用CGLTB动态代理
![在这里插入图片描述](https://img-blog.csdnimg.cn/381fd34db9554f36a9eb7a899b262b90.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAYWxpdmVsaWZl,size_20,color_FFFFFF,t_70,g_se,x_16)
AOP-底层原理(JDK动态代理实现)
(1)创建接口,定义方法
public interface User {
public int add(int a,int b);
public String id(String id);
}
(2)创建接口实现类,实现方法
public class User1Impl implements User {
public int add(int a, int b) {
return a+b;
}
public String id(String id) {
return id;
}
}
(3) 使用Proxy类创建接口代理对象
public class JDKProxy {
public static void main(String[] args) {
//创建接口实现类代理对象
Class[] interfaces={User.class};
User1Impl user1=new User1Impl();
//因为代理对象是接口 所以对他进行一下强转
User user =(User) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new User1Proxy(user1));
int result = user.add(2, 3);
System.out.println(result);
}
}
//创建代理对象代码
class User1Proxy implements InvocationHandler {
//把创建的是谁的代理对象,就把谁传递过来
//通过有参构造进行传递
private Object obj;
public User1Proxy(Object obj) {
this.obj = obj;
}
//增强的逻辑
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//方法之前
System.out.println("方法执行之前。。。。"+method.getName()+"传递的参数.。。"+ Arrays.toString(args));
//被增强的方法
Object in = method.invoke(obj, args);
//方法之后
System.out.println("方法执行之后"+obj);
return in;
}
}
执行之后的结果
AOP-操作术语
1、连接点
类里面哪些方法可以被增强,这些方法被称为连接点
2、切入点
实际被真正增强的方法被称为切入点
3、通知(增强)
实际增强的逻辑部分被称为通知(增强)
通知有很多种类型
前置通知@Before、后置通知(返回通知)@AfterReturning、环绕通知@Around、异常通知@AfterThrowing、最终通知@After
4、切面
是动作的操作
把你的通知应用到切入点的过程
AOP-准备工作
1、spring框架一般基于AspectJ实现AOP操作
(1)什么是AspectJ
AspectJ不是Spring组成部分,独立的AOP框架,一般把AspectJ和spring框架一起使用,进行AOP操作
2、基于AspectJ实现AOP操作两种操作方式
(1)基于Xml配置文件实现
(2)基于注解方式实现
3、在项目工程里面引入AspectJ相关依赖
4、切入点表达式
(1)切入点表达式作用:知道对哪个类里面的哪个方法进行增强
(2)语法结构:execution(【权限修饰符】[【返回类型】【类全路径】【方法名称】(【参数列表】))
举例1:对service包下的BookService类里面的add进行增强(*表示任意类型的修饰符)
execution(*service.BookService.add(参数,参数))
举例2:对service包下的BookService类里面的所有方法进行增强(*表示所有方法)
execution(service.BookService.(参数,参数))
举例3:对service包下所有类所有方法都进行增强
execution(service..*(参数,参数))
AOP操作(AspectJ配置文件)
1、创建类,在类里面定义方法
2、创建增强类(编写增强逻辑 )
在增强类里面,创建方法,让不同的方法代表不同的类型
3、进行通知的配置
(1)在spring配置文件中,开启注解扫描
(2)使用注解创建User和UserProxy对象
(3)在增强类上面添加注解@Aspect
(4)在spring配置文件中开启生成代理对象
<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 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="Aop.User1"></context:component-scan>
</beans>
相同切入点抽取
假如有多个相同切入点 可以使用
@Pointcut
注解把多个相同切入点抽取出来 放进一个方法体中 其他需要用到的直接调用此方法就行了
有多个增强类对同一个方法进行增强 ,可以设置增强类的优先级
在增强类上面添加注解@Order(数字类型值) 注:数字类型值越小,优先级越高
aop基于配置文件配置 了解即可
id=p 是给切入点取的名字 aspect ref=“bookProxy” 指的是增强类 ,before 方法作用在id=p上面 之前执行
完全使用注解开发,不需要创建xml文件
第一个@为声明配置类
第二个@开启组件扫描
第三个@为生成aspectj的代理对象