Maven与代理模式:构建高效Java应用的双重利器

在这篇文章中,我们将深入探讨Maven的核心功能和基本使用方法,揭示其在项目管理和构建过程中的强大优势。

同时,我们还将介绍动态代理和静态代理的概念。

特别是通过Proxy和InvocationHandler,我们将具体演示动态代理的实现方式,帮助你理解这一技术如何提升代码的灵活性和可维护性。

这篇文章将为你提供实用的知识与技巧,无论你是Maven的新手还是希望进一步掌握代理模式的开发者,都能在这里找到有价值的内容。

Maven

Maven似乎专门为Java项目打造的管理和构建工具。

Maven主要功能:

  • 提供了一套标准化的项目结构
  • 提供了一套标准化的构建流程
  • 提供了一套依赖管理机制
  • Maven使用groupId、artifactId、version唯一定位一个依赖。
  • Maven中声明一个依赖项可以自动下载和导入classpath。

Maven作用:

  • 解决了依赖管理,当我们写项目时,需要一个jar包,但是这个jar包还依赖其他的jar包。通过Maven我们就可以不用考虑这个问题,Maven会自动导入我们指定的jar包和其相依赖的jar包。

Maven定义了几种依赖关系

  • compile(默认),编译时需要用到该jar包
  • test,编译Test时需要用到该jar包
  • runtime,编译时不需要,但运行时需要用到
  • provided,编译时需要用到,但运行时由JDK或某个服务器提供

唯一ID

  • 对于某个依赖,Maven只需要3个变量即可唯一确定某个jar包:
  • groupId:属于组织的名称,类似Java的包名;
  • artifactId:该jar包自身的名称,类似Java的类名;
  • version:该jar包的版本。
  • 通过上述3个变量,即可唯一确定某个jar包。Maven通过对jar包进行PGP签名确保任何一个jar包一经发布就无法修改。修改已发布jar包的唯一方法是发布一个新版本。
  • 因此,某个jar包一旦被Maven下载过,即可永久地安全缓存在本地。

代理模式

代理模式(Proxy Pattern)是一种结构型设计模式,它通过提供一个代理对象来控制对另一个对象的访问。代理对象在客户端和目标对象之间起到中介作用,可以在访问目标对象前后添加额外的逻辑。

代理就是为其他对象提供一种代理,以控制对这个对象的访问。

代理模式的分类

1.静态代理

角色分析:
  • 抽象角色:一般会使用接口或者抽象类来解决
  • 真实角色:被代理的角色
  • 代理角色:代理真实角色,代理真实角色后,我们一般做一些附属操作
  • 客户:访问代理对象的人

代码步骤:

  1. 接口
  2. 真实角色
  3. 代理角色
  4. 客户端访问代理角色

静态代理好处:

  • 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
  • 公共业务就交给代理角色!实现类业务的分工!
  • 公共业务发生扩展的时候,方便集中管理!

缺点:

  • 一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率会变低。

注意:

  • 改动原有的业务代码,在公司是大忌!!

2.动态代理(这个代理不用自己创建,不用像静态代理那样)

角色:

  • 动态代理和静态代理角色一样
动态代理的代理类是动态生成的,不是我们直接写好的。

动态代理分为两大类:基于接口的动态代理,基于类的动态代理

  • 基于接口:JDK的动态代理【我们在这里使用】
  • 基于类:cglib
  • java字节码实现:javasist

需要了解两个类:Proxy(代理)、InvocationHandler(调用处理程序)

InvocationHandler,接口,java.lang.reflect
  • InvocationHandler是由代理实例的调用处理程序实现的接口。
  • 每个代理实例都有一个关联的调用处理程序。当在代理实例上调用方法时,方法调用将被编码并分派到其调用处理程序的invoke方法。
  • 该接口的方法 invoke(Object proxy,方法 method,Object[] args),处理代理实例上的方法调用并返回结果
Proxy,实现类,java.lang.reflect
  • Proxy提供了静态方法来创建动态代理类和实例,它也是由这些方法创建的所有动态代理类的超类。

动态代理的好处:

  • 除了静态代理的好处;
  • 一个动态代理类代理的是一个接口,一般就是对应的一类业务;
  • 一个动态代理类可以代理多个类,只要是实现了同一个接口即可。

咳咳,这是一个万能公式!!!

//等会我们会用这个类,自动生成代理类!public class ProxyInvocationHandler implements InvocationHandler {    //被代理的接口    private Object target;    public void setRent(Object target){        this.target=target;    }    //生成得到代理类    public Object getProxy(){        return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);    }    @Override//    处理代理实例,并返回结果    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        //动态代理的本质,就是使用反射机制实现的!//        System.out.println("这里被实现了");        Object result = method.invoke(target, args);        return result;    }}
public class Client {    public static void main(String[] args) {        //真实角色        Host host = new Host();        //代理角色        ProxyInvocationHandler pih = new ProxyInvocationHandler();        //通过调用程序处理角色来处理我们要调用的接口对象!        pih.setRent(host);        Rent proxy = (Rent)pih.getProxy();        System.out.println(proxy.rent());     }}

为什么要使用代理?

首先,为什么要使用代理?在一个成熟的系统中,如果我们想在不改变源码的基础上增加一些功能,就需要再套一层代理。在这个代理中实现我们要增加的功能。这里可以使用静态代理来实现。但是静态代理有一些问题,比如会增加代码量,影响效率。这时可以使用动态代理。

动态代理使用 Proxy 和 InvocationHandler 这两个类,可以对一个类,甚至多个类(只要它们实现了同一个接口)进行代理。通过这两个类,可以实现动态加载代理类,而不需要创建静态代理类。当动态代理对象生成时,通过某种机制触发 InvocationHandler 中的 invoke 方法,从而调用接口实现类对象的方法。同时,可以在 invoke 方法中实现其他额外的代码,这正是我们需要的。

这样的动态代理,既可以不改变原有的代码,又可以通过较少的代码量实现新增加的功能,漂亮!

#Java##Java后端##项目管理#
Java面试题 文章被收录于专栏

本专栏汇总了大量的Java面试题和Java面经,希望对大家有所帮助!

全部评论

相关推荐

1 收藏 评论
分享
牛客网
牛客企业服务