Java实现动态代理的实例代码

目录
  • 前言
  • 静态代理
  • 动态代理
  • CGLib实现动态代理
  • 总结

前言

动态代理在Java中有着广泛的应用,比如Spring AOP、Hibernate数据查询、测试框架的后端mock、RPC远程调用、Java注解对象获取、日志、用户鉴权、全局性异常处理、性能监控,甚至事务处理等。

代理,指的是使用代理对象代替对其它对象的访问,简单点说,你求职时找的中介就是代理,那么在Java中,代理如何体现呢?

静态代理

我们首先需要知道,何为静态代理?静态代理指的是在编译期就对目标对象的方法进行增强,例如:

public class TestDemo {

    interface EmailService {
        void sendEmail(String emailContent);
    }

    static class EmailServiceImpl implements EmailService{

        @Override
        public void sendEmail(String emailContent) {
            System.out.println("发送了一封邮件,内容为:" + emailContent);
        }
    }

    public static void main(String[] args) {
        EmailService emailService = new EmailServiceImpl();
        emailService.sendEmail("hello");
    }
}

现在若是想在发送邮件之前获取一下当前的时间,则可以使用代理类对发邮件的方法进行增强:

public class TestDemo {

    interface EmailService {
        void sendEmail(String emailContent);
    }

    static class EmailServiceImpl implements EmailService{

        @Override
        public void sendEmail(String emailContent) {
            System.out.println("发送了一封邮件,内容为:" + emailContent);
        }
    }

    static class EmailProxy implements EmailService{

        private final EmailService emailService;

        public EmailProxy(EmailService emailService) {
            this.emailService = emailService;
        }

        @Override
        public void sendEmail(String emailContent) {
            System.out.println(LocalDateTime.now());
            emailService.sendEmail(emailContent);
        }
    }

    public static void main(String[] args) {
        EmailService emailProxy = new EmailProxy(new EmailServiceImpl());
        emailProxy.sendEmail("hello");
    }
}

静态代理的缺点非常明显,编写麻烦,且可扩展性不强,而动态代理的出现,将彻底解决这些问题。

动态代理

动态代理与静态代理恰恰相反,动态代理是在运行期对目标对象的某个方法进行增强,比如仍然是发邮件的服务,使用动态代理,即可这样实现:

public class TestDemo {

    interface EmailService {
        void sendEmail(String emailContent);
    }

    static class EmailServiceImpl implements EmailService {

        @Override
        public void sendEmail(String emailContent) {
            System.out.println("发送了一封邮件,内容为:" + emailContent);
        }
    }

    public static void main(String[] args) {
        EmailService emailService = new EmailServiceImpl();
        EmailService emailProxy = (EmailService) Proxy.newProxyInstance(EmailServiceImpl.class.getClassLoader(), EmailServiceImpl.class.getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println(LocalDateTime.now());
                Object result = method.invoke(emailService, args);
                return result;
            }
        });
        emailProxy.sendEmail("hello");
    }
}

使用JDK提供的Proxy和InvocationHandler类能够轻松实现动态代理,但这种方式也是有局限性的,就是被增强的类必须实现了接口,因为Proxy的参数中需要接收类的接口信息。

CGLib实现动态代理

CGLib的出现,打破了这一僵局,使用CGLib,能够增强任意的对象方法,即使你没有实现任何接口,因为它是通过继承的方式进行增强的。

下面就来演示一下如何使用CGLib,首先引入依赖:

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>

实现如下:

public class TestDemo {

    static class EmailServiceImpl {
        public void sendEmail(String emailContent) {
            System.out.println("发送了一封邮件,内容为:" + emailContent);
        }
    }

    public static void main(String[] args) {
        EmailServiceImpl emailService = new EmailServiceImpl();
        EmailServiceImpl emailProxy = (EmailServiceImpl) Enhancer.create(emailService.getClass(), new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                System.out.println(LocalDateTime.now());
                Object obj = methodProxy.invokeSuper(o, args);
                return obj;
            }
        });
        emailProxy.sendEmail("hello");
    }
}

它的写法与JDK提供的方式类似,通过Enhancer类的create()方法即可增强一个对象,并传入对象的Class对象和一个MethodInterceptor接口的实现类,并在intercept()方法中对原方法进行增强。

总结

到此这篇关于Java实现动态代理的文章就介绍到这了,更多相关Java实现动态代理内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 十分钟理解Java中的动态代理

    若代理类在程序运行前就已经存在,那么这种代理方式被成为 静态代理 ,这种情况下的代理类通常都是我们在Java代码中定义的. 通常情况下, 静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类. 一.概述 1. 什么是代理 我们大家都知道微商代理,简单地说就是代替厂家卖商品,厂家"委托"代理为其销售商品.关于微商代理,首先我们从他们那里买东西时通常不知道背后的厂家究竟是谁,也就是说,"委托者"对我们来说是不可见的;其次,微商代理主要以朋友圈的人为目标客户,这就

  • Java动态代理的应用详解

    动态代理其实就是java.lang.reflect.Proxy类动态的根据您指定的所有接口生成一个class byte,该class会继承Proxy类,并实现所有你指定的接口(您在参数中传入的接口数组):然后再利用您指定的classloader将 class byte加载进系统,最后生成这样一个类的对象,并初始化该对象的一些值,如invocationHandler,以即所有的接口对应的Method成员. 初始化之后将对象返回给调用的客户端.这样客户端拿到的就是一个实现你所有的接口的Proxy对象

  • Java中反射动态代理接口的详解及实例

    Java语言中反射动态代理接口的解释与演示 Java在JDK1.3的时候引入了动态代理机制.可以运用在框架编程与平台编程时候捕获事件.审核数据.日志等功能实现,首先看一下设计模式的UML图解: 当你调用一个接口API时候,实际实现类继承该接口,调用时候经过proxy实现. 在Java中动态代理实现的两个关键接口类与class类分别如下: java.lang.reflect.Proxy java.lang.reflect.InvocationHandler 我们下面就通过InvocationHan

  • 详解java中动态代理实现机制

    代理模式是常用的java设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务. JAVA各种动态代理实现的比较 接口 interface AddInterface{ int add(int a, int b); } interface SubInterfa

  • java实现动态代理方法浅析

    一些Java项目中在mybatis与spring整合中有MapperScannerConfigurer的使用,该类通过反向代理自动生成基于接口的动态代理类. 有鉴于此,本文浅析了java的动态代理. 本文使用动态代理模拟处理事务的拦截器. 接口: public interface UserService { public void addUser(); public void removeUser(); public void searchUser(); } 实现类: public class

  • 代理模式之Java动态代理实现方法

    今天一个偶然的机会我突然想看看JDK的动态代理,因为以前也知道一点,而且只是简单的想测试一下使用,使用很快里就写好了这么几个接口和类:接口类:UserService.java 复制代码 代码如下: package com.yixi.proxy;public interface UserService {    public int save() ;    public void update(int id);} 实现类:UserServiceImpl.java 复制代码 代码如下: packag

  • java代理模式与动态代理模式详解

    1.代理模式 所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 生活中的例子:过年加班比较忙,没空去买火车票,这时可以打个电话到附近的票务中心,叫他们帮你买张回家的火车票,当然这会附加额外的劳务费.但要清楚票务中心自己并不卖票,只有火车站才真正卖票,票务中心卖给你的票其实是通过火车站实现的.这点很重要!

  • java动态代理和cglib动态代理示例分享

    java动态代理类可以分为两种. 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译.在程序运行前,代理类的.class文件就已经存在了. 动态代理:在程序运行时,运用反射机制动态创建而成. 一.首先我们进行java动态代理的演示. 现在我们有一个简单的业务接口Saying,如下: 复制代码 代码如下: package testAOP;public interface Saying {public void sayHello(String name);    public void ta

  • 详解java动态代理的2种实现方式

    java的动态代理在接java的api上有说明,这里就不写了.我理解的代理: 对特定接口中特定方法的功能进行扩展,这就是代理.代理是通过代理实例关联的调用处理程序对象调用方法. 下面通过一个例子看一下: 接口: public interface Num { void show(); int getNum(); int getProduct(int x); } 实现类: public class MyNum implements Num { @Override public int getNum(

  • 基于接口实现java动态代理示例

    Subject.java 复制代码 代码如下: package _20140416_; import java.util.List; public interface Subject {   public String say(String name,int age);   public List<Person> getAllList(String name);} RealSubject.java 复制代码 代码如下: package _20140416_; import java.util.

随机推荐