Java - Maven+代理

发布于:2024-10-09 ⋅ 阅读:(18) ⋅ 点赞:(0)

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 方法中实现其他额外的代码,这正是我们需要的。

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