• SpringAOP的原理及仿写


    什么是AOP

    AOP (Aspect Orient Programming),直译过来就是 面向切面编程。AOP 是一种编程思想,是面向对象编程(OOP)的一种补充。面向对象编程将程序抽象成各个层次的对象,而面向切面编程是将程序抽象成各个切面。

    为什么需要AOP

    想象下面的场景,开发中在多个模块间有某段重复的代码,我们通常是怎么处理的?显然,没有人会靠“复制粘贴”吧。在传统的面向过程编程中,我们也会将这段代码,抽象成一个方法,然后在需要的地方分别调用这个方法,这样当这段代码需要修改时,我们只需要改变这个方法就可以了。然而需求总是变化的,有一天,新增了一个需求,需要再多出做修改,我们需要再抽象出一个方法,然后再在需要的地方分别调用这个方法,又或者我们不需要这个方法了,我们还是得删除掉每一处调用该方法的地方。实际上涉及到多个地方具有相同的修改的问题我们都可以通过 AOP 来解决。

    AOP的实现

    AOP本质上其实是代理模式,定义切入点和定义增强处理,一旦定义了合适的切入点和增强处理,AOP框架将自动生成AOP代理。

    jdk动态代理实现
    基本类

    //定义的接口HelloService
    public interface HelloService {
        void sayHello();
    }
    //接口的实现类
    public class HelloServiceImpl implements HelloService {
        public void sayHello() {
            System.out.println("Hello");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    通知类

    //Advice,继承了 InvocationHandler 接口
    public interface Advice extends InvocationHandler {
    	
    }
    //实现了 Advice 接口,是一个前置通知
    public class BeforeAdvice implements Advice{
    	//真实类的对象
        private Object bean;
        //通知内容
        private MethodInvocation methodInvocation;
        public BeforeAdvice(Object bean,MethodInvocation methodInvocation){
            this.bean=bean;
            this.methodInvocation=methodInvocation;
        }
       //当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        	//前置通知内容
            methodInvocation.invoke();
            // 当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
            method.invoke(bean, args);
            return null;
        }
    }
    //通知内容,实现类包含了切面逻辑
    public interface MethodInvocation {
        void invoke();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    AOP实现类

    //生成代理类
    public class SimpleAOP {
        public static Object getProxy(Object bean,Advice advice){
            return Proxy.newProxyInstance(SimpleAOP.class.getClassLoader(),bean.getClass().getInterfaces(), advice);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    测试类

    public class TestAop {
        public static void main(String[] args) {
            // 1. 创建一个 MethodInvocation 实现类
            MethodInvocation logTask = () -> System.out.println("log task start");
            HelloServiceImpl helloServiceImpl = new HelloServiceImpl();
    
            // 2. 创建一个 Advice
            Advice beforeAdvice = new BeforeAdvice(helloServiceImpl,logTask);
    
            // 3. 为目标对象生成代理
            HelloService helloServiceImplProxy = (HelloService) SimpleAOP.getProxy(helloServiceImpl,beforeAdvice);
    
    		//调用方法
            helloServiceImplProxy.sayHello();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    附加

    Object invoke(Object proxy, Method method, Object[] args) throws Throwable
     
    proxy:  - 指代我们所代理的那个真实对象
    method: - 指代的是我们所要调用真实对象的某个方法的Method对象
    args:  - 指代的是调用真实对象某个方法时接受的参数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
     
    loader:      一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
     
    interfaces:  一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
     
    h:           一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 相关阅读:
    【经纬恒润】自动驾驶感知算法岗位一面
    快捷键操作
    [xmake]构建静态库和动态库
    论文网站有哪些?
    Centos乱码,jar包输出乱码
    11. 一文快速学懂常用工具——网络工具(下)
    安装Apachi
    manjaro gnome 记录 3 配置国内镜像源
    java毕业生设计校园招聘管理系统计算机源码+系统+mysql+调试部署+lw
    Java HashSet详解
  • 原文地址:https://blog.csdn.net/weixin_46101560/article/details/125507165