动态代理AOP机制分析

这篇具有很好参考价值的文章主要介绍了动态代理AOP机制分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

有一个接口Vehicle,接口里有个run方法,有一个汽车类和一个轮船类,实现了这个接口。
要求在运行Car对象的run方法或运行ship对象的run方法前输出一些日志。
交通工具开始运行了…
轮船在海上running
交通工具停止运行了…

交通工具开始运行了…
轮船在海上running
交通工具停止运行了…

我们可以使用动态代理解决这个问题

定义接口

public interface Vehicle {
    void run();

    String fly(int height);
}

汽车类

public class Car implements Vehicle{
    @Override
    public void run() {
        System.out.println("小汽车在公路running....");
    }

    @Override
    public String fly(int height) {
        return "小车飞翔的高度 " + height;
    }
}

轮船类

public class Ship implements Vehicle{
    @Override
    public void run() {
        System.out.println("轮船在海上running");
    }

    @Override
    public String fly(int height) {
        return "轮船飞翔的高度 " + height;
    }
}

定义代理类

public class VehicleProxyProvider {
    //定义一个属性
    //target_vehicle表示真正要执行的对象
    private Vehicle target_vehicle;


    public VehicleProxyProvider(Vehicle target_vehicle) {
        this.target_vehicle = target_vehicle;
    }


    public Vehicle getProxy() {
        //得到类加载器
        ClassLoader classLoader = target_vehicle.getClass().getClassLoader();
        Class<?>[] interfaces = target_vehicle.getClass().getInterfaces();
        //匿名内部类
        InvocationHandler invocationHandler = new InvocationHandler() {
            /**
             * @param proxy  the proxy instance that the method was invoked on
             * @param method the {@code Method} instance corresponding to
             *               the interface method invoked on the proxy instance.  The declaring
             *               class of the {@code Method} object will be the interface that
             *               the method was declared in, which may be a superinterface of the
             *               proxy interface that the proxy class inherits the method through.
             * @param args   an array of objects containing the values of the
             *               arguments passed in the method invocation on the proxy instance,
             *               or {@code null} if interface method takes no arguments.
             *               Arguments of primitive types are wrapped in instances of the
             *               appropriate primitive wrapper class, such as
             *               {@code java.lang.Integer} or {@code java.lang.Boolean}.
             * @return
             * @throws Throwable
             */
            //使用反射+动态代理
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("交通工具开始运行了....");
                System.out.println(method);
                Object result = method.invoke(target_vehicle, args);
                System.out.println("交通工具停止运行了");
                return result;
            }
        };
        Vehicle proxy = (Vehicle) Proxy.newProxyInstance(classLoader,interfaces,invocationHandler);
        return proxy;
    }
}

测试

public class Main {
    @Test
    public void proxyRun() {
        Vehicle vehicle = new Ship();
        ProxyProvider proxyProvider = new ProxyProvider(vehicle);
        Vehicle proxy = proxyProvider.getProxy();
        proxy.run();


        Vehicle car = new Car();
        ProxyProvider proxyProvider1 = new ProxyProvider(car);
        Vehicle proxy1 = proxyProvider1.getProxy();
        String fly = proxy1.fly(100);
        System.out.println(fly);
    }
}

动态代理AOP机制分析,Spring,java,AOP,动态代理,代理模式

无独有偶
我们可以在最为核心的invoke方法前后打印输出日志,这也就是AOP的底层机制所在之处。

先定义一个接口

public interface SmartAnimal {
    int getSum(int a, int b);

    int getSub(int a, int b);
}

再定义接口的实现类

public class Sum implements SmartAnimal {
    @Override
    public int getSum(int a, int b) {
        int sum = a + b;
        return sum;
    }

    @Override
    public int getSub(int a, int b) {
        int c = a - b;
        return c;
    }
}

定义动态代理类

public class ProxyProvider {

    private final SmartAnimal smartAnimal;

    public ProxyProvider(SmartAnimal smartAnimal) {
        this.smartAnimal = smartAnimal;
    }

    public SmartAnimal getProxy() {
        ClassLoader classLoader = smartAnimal.getClass().getClassLoader();
        Class<?>[] interfaces = smartAnimal.getClass().getInterfaces();
        InvocationHandler invocationHandler = new InvocationHandler() {

            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                try {

                    SpaAop.before(proxy,method,args);
                    Object result = method.invoke(smartAnimal, args);
                    SpaAop.after(method,result);
                    return result;
                } catch (Exception e) {
                    System.out.println("方法执行异常-日志-方法名-" + method.getName() + "-异常类型=" + e.getClass().getName());
                    throw new RuntimeException(e);
                } finally {//不管是否出现异常方法最终都会执行到finally
                    System.out.println("方法最终结束-日志-方法名-" + method.getName());
                }

            }
        };
        SmartAnimal proxy =(SmartAnimal) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
        return proxy;
    }

}

把要输出的日志封装的一个类的静态方法中,这样就可以通过类名.方法名来调用实现了解耦,同时也可以在方法中获取参数

public class SpaAop {
    public static void before(Object proxy, Method method, Object[] args) {
        System.out.println("before方法执行前日志-方法名" +method.getName() + "-参数-"+ Arrays.toString(args));
    }


    public static void after(Method method, Object result) {
        System.out.println("after日志-方法名" + method.getName() + "-结果result=" + result);

    }
}

测试 运行截图

public class TestProxy {
    @Test
    public void test() {
        Sum sum = new Sum();
        ProxyProvider proxyProvider = new ProxyProvider(sum);
        SmartAnimal proxy = proxyProvider.getProxy();
        proxy.getSum(8, 9);
        proxy.getSub(6,89);
    }
}

动态代理AOP机制分析,Spring,java,AOP,动态代理,代理模式文章来源地址https://www.toymoban.com/news/detail-605786.html

到了这里,关于动态代理AOP机制分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • spring的aop动态代理对象注入时机

    bean生命周期: bean实例化 populateBean填充属性 invokeAwareMethods调用aware方法 postProcessBeforeInitialization后置处理器before方法 initializeBean初始化bean postProcessAfterAfterInitialization后置处理器after方法 代理对象注入有两种情况:提前和非提前生成代理对象 1. 非提前生成代理对象 依赖于bea

    2024年02月12日
    浏览(42)
  • Spring Boot 中的 AOP,到底是 JDK 动态代理还是 Cglib 动态代理

    大家都知道,AOP 底层是动态代理,而 Java 中的动态代理有两种实现方式: 基于 JDK 的动态代理 基于 Cglib 的动态代理 这两者最大的区别在于基于 JDK 的动态代理需要被代理的对象有接口,而基于 Cglib 的动态代理并不需要被代理对象有接口。 那么,Spring 中的 AOP 是怎么实现的

    2024年02月12日
    浏览(34)
  • Spring 使用注解开发、代理模式、AOP

    在Spring4之后,要使用注解开发,必须要保证AOP的包导入了 项目搭建: 在配置文件中导入约束,增加注解支持 bean 实体类 @Component 注解 xml配置 测试: 属性如何注入 衍生的注解 @Component 有几个衍生的注解,我们在web开发中,会按照MVC三层架构分层 dao层: @Repository 等价于poj

    2024年02月13日
    浏览(51)
  • Spring AOP 学习(动态代理、JdbcTemplate、Junit)

    Proxy  jdk动态代理,面向接口 cglib   第三方动态代理,面向父类 在 不修改原有代码 ,或者没有办法修改原有代码的情况下, 增强对象功能 ,使用代理对象代替原来的对象去完成功能,进而达到拓展功能的目的 JDK Proxy 动态代理是 面向接口 的动态代理,一定要有接口和实现

    2024年02月08日
    浏览(40)
  • 54.Spring的AOP是在哪里创建的动态代理?

    正常的Bean会在Bean的生命周期的‘初始化’后, 通过BeanPostProcessor.postProcessAfterInitialization创建aop的动态代理 还有一种特殊情况: 循环依赖的Bean会在Bean的生命周期‘属性注入’时存在的循环依赖的情况下, 也会为循环依赖的Bean 通过MergedBeanDefinitionPostProcessor.postProcessMergedBe

    2024年02月02日
    浏览(38)
  • JDK 动态代理(Spring AOP 的原理)(面试重点)

            也叫委托模式.定义:为其他对象提供⼀种代理以控制对这个对象的访问.它的作⽤就是通过提供⼀个代理类,让我们 在调⽤⽬标⽅法的时候,不再是直接对⽬标⽅法进⾏调⽤,⽽是通过代理类间接调⽤,在某些情况下,⼀个对象不适合或者不能直接引⽤另⼀个对象,⽽代

    2024年01月22日
    浏览(40)
  • spring动态代理失效,AOP失效,事务@Transactional失效原因

    事务基于@Transactional注解和AOP(动态代理) 对于基于接口动态代理的 AOP 事务增强来说,由于接口的方法都必然是 public 的,这就要求实现类的实现方法也必须是 public 的(不能是 protected、private 等),同时不能使用 static 的修饰符。所以,可以实施接口动态代理的方法只能是

    2024年02月15日
    浏览(48)
  • Spring AOP (面向切面编程)原理与代理模式—实例演示

    Spring 中文文档 (springdoc.cn) Spring | Home 官网         Java是一个面向对象(OOP)的语言,但它有一些弊端。虽然使用OOP可以通过组合或继承的方式来实现代码的重用。但当我们需要为多个不具有继承关系的对象(一般指的是两个不同的类,它们之间没有继承自同一个父类或接

    2024年02月15日
    浏览(54)
  • B057-spring增强 依赖注入 AOP 代理模式 创建Bean

    DI:依赖注入 环境准备,即写一个spring测试,见工程 构造器注入 即使用构造器来给Bean的对象的属性赋值 MyBean OtherBean SpringTest-Context.xml SpringTest setter方法注入 即用setter方法给bean对象的属性赋值 MyBean OtherBean SpringTest-Context.xml SpringTest AOP 概念 事务管理:比如可以抽取try catch的

    2024年02月12日
    浏览(48)
  • Spring5系列学习文章分享---第三篇(AOP概念+原理+动态代理+术语+Aspect+操作案例(注解与配置方式))

    开篇: 欢迎再次来到 Spring 5 学习系列!在这个博客中,我们将深入研究 Spring 框架的AOP概念+原理+动态代理+术语+Aspect+操作案例(注解与配置方式)。 概念 什么是AOP (1)面向切面编程(方面),利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得 业务逻辑各部分之间的

    2024年01月24日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包