👴发现尽量控制字数更好1点,这真的不是开摆🤗
厦工为什么不上网课😭😭😭😭😭😭😭
AOP
AOP(Aspect Oriented Programming)面向切面编程,是一种不修改源码的情况下,添加功能的种编程思想,OOP有两个不足:对于没有继承关系类的横向共用性,无法处理,也无法动态增加功能。
目的降低耦合

1、AOP术语
| 术语 | 解释 |
|---|---|
| 切面(Aspect) | 由切点和增强组成,在Java代码中对于一个切面类 |
| 连接点(JointPoint) | 程序执行的某个位置,如函数调用、函数执行、构造函数调用、获取或设置遍历、类初始化等 |
| 切入点(Pointcut) | 也就是特定的连接点 |
| 增强(Advice) | 织入到目标连接点的代码,也就是额外功能的代码 |
| 织入(Weaving) | 增强添加到目标连接点的过程 |
| 前置(Before)、后置(After)、Around(环绕) | 织入的方位,可前,可后 |
| 代理(Proxy) | 是实现AOP的主要奇数,在代理类种包含了原始类和增强代码的功能 |
2、AOP底层原理
动态代理
2.1、使用JDK动态代理
有接口,使用JDK动态代理
Proxy类
newProxyInstance()方法 , 三个参数
- 类加载
- 增强方法所在的类,这个类实现的接口,支持多个接口
- 实现这个接口
InvocationHandler,创建代理对象,写增强的部分
public interface UserDao {
public int add(int a,int b);
public String update(String id);
}
public class UserDaoImpl implements UserDao {
@Override
public int add(int a, int b) {
return a + b;
}
@Override
public String update(String id) {
return id;
}
}
代理对象
public class UserDaoProxy implements InvocationHandler {
private Object obj;
public UserDaoProxy(Object obj){
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("方法执行前..." + method.getName() + "传递的参数..." + Arrays.toString(args));
// 被增强的方法执行
Object res = method.invoke(obj,args);
System.out.println("方法之后执行" + obj);
return res;
}
}
测试
public class JDKProxy {
public static void main(String[] args) {
Class[] interfaces = {UserDao.class};
UserDaoImpl userDao = new UserDaoImpl();
UserDao dao =
(UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(),interfaces,new UserDaoProxy(userDao));
}
}
方法执行前...add传递的参数...[1, 2]
方法之后执行com.flzj.dao.UserDaoImpl@2b193f2d
3
2.2、没接口,使用CGLIB动态代理
创建子类代理对象,增强父类方法
class A extends B{
public void add(){
super.add(); // 调用父类的B
// 增强逻辑
}
}
3、基于AspectJ的AOP
AspectJ 不是Spring组成部分,独立AOP框架,一般把 AspectJ 和 Spring 框架一起使用AOP操作
3.1、注解方式
切入点表达式
execution([权限修饰符][返回类型][类全路径][方法名称]([参数列表]))
| 注解 | 作用 |
|---|---|
| @Before | 前置通知 |
| @AfterReturning | 后置通知(返回通知) |
| @After | 最终通知 |
| @AfterThrowing | 异常通知 |
| @Around | 环绕通知 |
| @Pointcut(value) | 相同切入点的抽取 |
| @Order(数字类型值) | 设置优先级(对类使用),数值越小越优先 |
@Before(value = "execution(* com.flzj.proxy.User.add(..))")
public void before(){
System.out.println("before........");
}
@AfterReturning(value = "execution(* com.flzj.proxy.User.add(..))")
public void afterReturn(){
System.out.println("afterReturn...");
}
@After(value = "execution(* com.flzj.proxy.User.add(..))")
public void after(){
System.out.println("after.......");
}
@AfterThrowing(value = "execution(* com.flzj.proxy.User.add(..))")
public void afterThrowing(){
System.out.println("afterThrowing....");
}
@Around(value = "execution(* com.flzj.proxy.User.add(..))")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕之前");
proceedingJoinPoint.proceed();
System.out.println("环绕之后");
}
环绕之前
before........
add........
环绕之后
after.......
afterReturn...
加上bug
int i = 16 / 0;
环绕之前
before........
after.......
afterThrowing....
相同切入点,需要先写一个方法
@Pointcut(value = "execution(* com.flzj.proxy.User.add(..))")
public void pointdemo(){}
@Before(value = "pointdemo()")
public void before(){
System.out.println("before........");
}
@AfterReturning(value = "pointdemo()")
public void afterReturn(){
System.out.println("afterReturn...");
}
...
需要
1、使用aop名称空间 2、开启组件扫描 3、开启Aspect生成代理对象
<!-- 1 -->
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
...
<!-- 2 -->
<context:component-scan base-package="com.flzj.proxy"></context:component-scan>
<!-- 3 开启Aspect生成代理对象 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
3.2、配置方式
<aop:config >标签 配置aop增强
<aop:pointcut >标签 配置切入点 id (给切入点取个名字)和 excution 属性
<aop:aspect >标签 配置切面 ref 属性
<aop:before/after/…>标签 增强作用在具体方法 method 属性 pointcut-ref 属性
<bean id="book" class="com.flzj.bean.Book"></bean>
<bean id="bookProxy" class="com.flzj.bean.BookProxy"></bean>
<aop:config>
<aop:pointcut id="ppp" expression="execution(* com.flzj.bean.Book.sell(..))"/>
<aop:aspect ref="bookProxy">
<aop:before method="proxyMethod" pointcut-ref="ppp"/>
</aop:aspect>
</aop:config>
🈲 禁止速通,🈲 禁止速通,🈲 禁止速通,🈲 禁止速通🈲 禁止速通,🈲 禁止速通,🈲 禁止速通,🈲 禁止速通🈲 禁止速通,🈲 禁止速通,🈲 禁止速通,🈲 禁止速通
本文详细探讨了AOP的原理,包括JDK动态代理(带接口与无接口实现)和AspectJ的注解与配置方式,展示了如何通过切面编程降低模块间的耦合度。





