java--代理

在软件开发中,代理模式是一种非常常见的设计模式。它允许我们通过一个代理对象间接访问目标对象,从而在不修改目标对象的情况下增强其功能。代理模式广泛应用于日志记录、权限校验、事务管理、延迟加载等场景。本文将带你深入了解Java中的代理模式,包括静态代理和动态代理的实现方式。

一、什么是代理


给目标对象提供一个代理对象,并且由代理对象控制着对目标对象的引用

在程序中,代理模式的核心思想是:

代理对象:代替目标对象执行某些操作。

目标对象:实际执行业务逻辑的对象。

增强功能:在调用目标对象方法前后,代理对象可以添加额外的逻辑。

二、代理的目的

代理模式的主要目的是在不修改目标对象的情况下增强其功能。具体来说,代理模式可以实现以下目标:

1、控制访问:通过代理对象的方式间接的访问目标对象,防止直接访问目标对象给系统带来的不必要的复杂性

2、功能增强:通过代理业务对原有业务进行增强。

三、如何实现代理


Java中实现代理模式主要有两种方式:

静态代理,通过JDK实现

动态代理,通过JDK或者cglib实现

下面我们分别介绍这两种方式。

静态代理
在Java中,静态代理是一种设计模式,它通过创建一个代理类来间接访问目标类,从而在不修改目标类的情况下增强其功能。静态代理的核心思想是:手动编写代理类,代理类和目标类实现相同的接口,代理类持有目标类的引用,并在调用目标类方法的前后添加额外的逻辑。

代码实例:

(1)目标类ClothesFactory



public class ClothesFactory implements ByClothes{
 
    public void clothes(String size){
        System.out.println("已经给您定制好了一件大小为"+size+"的衣服");
    }
 
    public void 机器处理(){
 
    }
 
    public void 原材料(){}
}


这是实际执行业务逻辑的类,它实现了 ByClothes 接口,并提供了 clothes 方法的具体实现。

(2)代理类Proxy 

public class Proxy implements ByClothes {
 
    private ClothesFactory clothesFactory = new ClothesFactory();
 
 
    @Override
    public void clothes(String size) {
        FrontService();
        clothesFactory.clothes(size);
        endService();
    }
 
 
    //前置服务
    public void FrontService() {
        System.out.println("根据您的需求进行市场调研");
    }
 
    //前置服务
    public void endService() {
        System.out.println("为您提供一条龙的包办服务");
    }
 
 
}

代理类也实现了 ByClothes 接口,它持有一个 ClothesFactory 的实例(目标类的引用),在调用目标类的 clothes 方法前后,代理类可以添加额外的逻辑(如 FrontService 和 endService)。

(3)接口ByClothes 

public interface ByClothes {
    public abstract  void clothes(String size);
}


这是一个接口,定义了 clothes 方法,目标类 ClothesFactory 和代理类 Proxy 都实现了这个接口。

 (4)客户端Test

public class Test {
    public static void main(String[] args){
        Proxy proxy =new Proxy();
        proxy.clothes("xxxl");
}
}


客户端通过代理类 Proxy 来调用 clothes 方法,客户端并不直接与目标类 ClothesFactory 交互,而是通过代理类间接访问。

静态代理的工作流程

客户端调用代理类的 clothes 方法。

代理类在调用目标类的 clothes 方法之前,执行前置逻辑(FrontService)。

代理类调用目标类的 clothes 方法,完成核心业务逻辑。

代理类在调用目标类的 clothes 方法之后,执行后置逻辑(endService)。

静态代理缺点:当目标类增多时,代理类直接增加代理的目标类,会造成代理关系混乱。

动态代理


动态代理是Java中一种更灵活的代理模式,动态代理的核心思想是:在运行时动态生成代理类,而不需要像静态代理那样为每个目标类手动编写代理类。

代码实例:

(1)InvocationHandler接口的实现类DyProxy

package com.qcby;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
public class DyProxy implements InvocationHandler {
 
    // 被代理的对象
    private Object o;
 
    // 构造方法,传入被代理的对象
    public DyProxy(Object o) {
        this.o = o;
    }
 
    // 获取代理对象
    public Object getProxyInterFace() {
        return Proxy.newProxyInstance(
            o.getClass().getClassLoader(), // 目标类的类加载器
            o.getClass().getInterfaces(), // 目标类实现的接口
            this // InvocationHandler 实例
        );
    }
 
    // 核心方法:代理逻辑
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        FrontService(); // 前置增强逻辑
        Object result = method.invoke(o, args); // 调用目标类的方法
        endService(); // 后置增强逻辑
        return result; // 返回方法执行结果
    }
 
    // 前置服务
    public void FrontService() {
        System.out.println("根据您的需求进行市场调研");
    }
 
    // 后置服务
    public void endService() {
        System.out.println("为您提供一条龙的包办服务");
    }
}

InvocationHandler:这是一个接口,动态代理的核心逻辑通过实现它的 invoke 方法来定义。

DyProxy:这是 InvocationHandler 的实现类,负责在运行时动态生成代理对象。

o:被代理的目标对象。
getProxyInterFace:通过 Proxy.newProxyInstance 方法生成代理对象。
invoke:在代理对象调用方法时,会执行 invoke 方法,在这里可以添加前置和后置逻辑。
(2)目标类ShootFactory

public class ShootFactory implements ByShoot {
    public void Shoot(String size) {
        System.out.println("已经为您定制好了一双大小为" + size + "的鞋子");
    }
}


目标类是实现特定接口的类,包含核心业务逻辑,动态代理可以代理任意实现了接口的目标类。 

 (3)接口ByShoot

 
public interface ByShoot {
    void Shoot(String size);
}


 动态代理要求目标类必须实现接口,因为 Proxy.newProxyInstance 需要接口信息来生成代理对象。

(4)客户端Test

public class Test {
    public static void main(String[] args) {
        ShootFactory shootFactory = new ShootFactory();
        ByShoot shoot = (ByShoot) new DyProxy(shootFactory).getProxyInterFace();
        shoot.Shoot("42");
    }
}


客户端通过 DyProxy 动态生成代理对象,并调用代理对象的方法,代理对象会在调用目标方法前后执行增强逻辑。

动态代理的工作流程

客户端调用 DyProxy 的 getProxyInterFace 方法,生成代理对象。

代理对象调用方法时,会触发 InvocationHandler 的 invoke 方法。

在 invoke 方法中:执行前置逻辑(FrontService),通过反射调用目标类的方法(method.invoke(o, args)),执行后置逻辑(endService)。

返回方法执行结果。

动态代理缺点:动态代理要求目标类必须实现接口,否则无法生成代理对象。

代理模式是Java中一种强大的设计模式,它通过代理对象间接访问目标对象,从而在不修改目标对象的情况下增强其功能。静态代理简单直观,但不够灵活;动态代理灵活性强,但必须依赖接口。在实际开发中,我们可以根据具体需求选择合适的代理方式。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值