搜索
首页Javajava教程java之动态代理

java之动态代理

Dec 01, 2016 pm 01:30 PM
java

一、动态代理引入

package cn2;
 
public interface IUserDAO {
    /**
     * 登录方法
     */
    public void login();
     
    /**
     * 注册方法
     */
    public void register();
 
}
package cn2;
 
public class UserDAOImpl implements IUserDAO {
 
    @Override
    public void login() {
        System.out.println("用户登录");
 
    }
 
    @Override
    public void register() {
        System.out.println("用户注册");
    }
 
}
package cn2;
 
public class Test {
    public static void main(String[] args) {
        IUserDAO dao = new UserDAOImpl();
        dao.register();
        dao.login();
         
         
    }
}

用户注册

用户登录


如果我要给每个方法都增加权限校验和日志记录的话,那么代码实现如下:

package cn2;
 
public interface IUserDAO {
    /**
     * 登录方法
     */
    public void login();
     
    /**
     * 注册方法
     */
    public void register();
 
}
package cn2;
 
public class UserDAOImpl implements IUserDAO {
 
    @Override
    public void login() {
        System.out.println("用户登录");
 
    }
 
    @Override
    public void register() {
        System.out.println("用户注册");
    }
 
}
package cn2;
 
public class UserDAOImpl2 implements IUserDAO {
    private void actionCheck(){
        System.out.println("权限检查");
    }
     
    private void record(){
        System.out.println("日志记录");
    }
     
    @Override
    public void login() {
        this.actionCheck();
        System.out.println("登录");
        this.record();
 
    }
 
    @Override
    public void register() {
        this.actionCheck();
        System.out.println("注册");
        this.record();
    }
 
}
package cn2;
 
public class Test {
    public static void main(String[] args) {
        IUserDAO dao = new UserDAOImpl2();
        dao.register();
        dao.login();
         
         
    }
}

权限检查

注册

日志记录

权限检查

登录

日志记录


为什么要单独写一个类去实现接口,并增加权限校验和日志记录呢?因为我们在设计的时候,要保证对扩展功能开发,对修改代码关闭的原则。我定义了一个新的类去实现接口,就是想扩展原来接口的功能,而不是在原有的实现类上修改。

但是,如果都这样设计,是很可怕的事情,如果需求一旦变更,那我们需要定义好多好多的实现类,太复杂了。怎么办?


在生活中,我们会遇到很多问题,比如:我要租房子,但是我不认识房东,怎么办?找中介。同样的道理,我自己不想在修改代码去增加权限检查和日志记录的功能,那么我找一个代理对象去帮我实现不就可以了吗?

动态代理:就是在程序运行过程中产生的这个对象。

在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口接可以生成动态代理对象。JDK只针对接口做代理。

Proxy类中的方法创建动态代理对象

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

   

最终会调用InvocationHandler的方法

Object invoke(Object proxy,Method method,Object[] args)
package cn2;
 
public interface IUserDAO {
    /**
     * 登录方法
     */
    public void login();
     
    /**
     * 注册方法
     */
    public void register();
 
}
package cn2;
 
public class UserDAOImpl implements IUserDAO {
 
    @Override
    public void login() {
        System.out.println("用户登录");
 
    }
 
    @Override
    public void register() {
        System.out.println("用户注册");
    }
 
}
package cn2;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
 
public class MyInvocationHandler implements InvocationHandler {
     
    private Object target;
    public MyInvocationHandler(Object target) {
        this.target = target;
    }
     
    /**
     *返回动态代理对象
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
         
        System.out.println("权限检查");
         
        Object invoke = method.invoke(target, args);
         
        System.out.println("日志记录");
        return invoke;
    }
 
}
package cn2;
 
import java.lang.reflect.Proxy;
 
public class Test {
    public static void main(String[] args) {
        //使用动态代理之前
        IUserDAO dao = new UserDAOImpl();
        dao.register();
        dao.login();
         
        System.out.println("-------------------");
         
        //使用动态代理之后
         
        IUserDAO proxy = (IUserDAO)Proxy.newProxyInstance(dao.getClass().getClassLoader(), dao.getClass().getInterfaces(), new MyInvocationHandler(dao));
        proxy.register();
        proxy.login();
         
    }
}

   

用户注册

用户登录

-------------------

权限检查

用户注册

日志记录

权限检查

用户登录

日志记录


声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
如何将Maven或Gradle用于高级Java项目管理,构建自动化和依赖性解决方案?如何将Maven或Gradle用于高级Java项目管理,构建自动化和依赖性解决方案?Mar 17, 2025 pm 05:46 PM

本文讨论了使用Maven和Gradle进行Java项目管理,构建自动化和依赖性解决方案,以比较其方法和优化策略。

如何使用适当的版本控制和依赖项管理创建和使用自定义Java库(JAR文件)?如何使用适当的版本控制和依赖项管理创建和使用自定义Java库(JAR文件)?Mar 17, 2025 pm 05:45 PM

本文使用Maven和Gradle之类的工具讨论了具有适当的版本控制和依赖关系管理的自定义Java库(JAR文件)的创建和使用。

如何使用咖啡因或Guava Cache等库在Java应用程序中实现多层缓存?如何使用咖啡因或Guava Cache等库在Java应用程序中实现多层缓存?Mar 17, 2025 pm 05:44 PM

本文讨论了使用咖啡因和Guava缓存在Java中实施多层缓存以提高应用程序性能。它涵盖设置,集成和绩效优势,以及配置和驱逐政策管理最佳PRA

如何将JPA(Java持久性API)用于具有高级功能(例如缓存和懒惰加载)的对象相关映射?如何将JPA(Java持久性API)用于具有高级功能(例如缓存和懒惰加载)的对象相关映射?Mar 17, 2025 pm 05:43 PM

本文讨论了使用JPA进行对象相关映射,并具有高级功能,例如缓存和懒惰加载。它涵盖了设置,实体映射和优化性能的最佳实践,同时突出潜在的陷阱。[159个字符]

Java的类负载机制如何起作用,包括不同的类载荷及其委托模型?Java的类负载机制如何起作用,包括不同的类载荷及其委托模型?Mar 17, 2025 pm 05:35 PM

Java的类上载涉及使用带有引导,扩展程序和应用程序类负载器的分层系统加载,链接和初始化类。父代授权模型确保首先加载核心类别,从而影响自定义类LOA

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),