代理

代理是一种设计模式
image
StarService.java

package com.itheima.demo4proxy;
// 明星行为接口
public interface StarService {
    void sing(String name);
    String dance();
}

Star.java

package com.itheima.demo4proxy;
 
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
 
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Star implements StarService{
    private String name;
 
    @Override
    public void sing(String name) {
        System.out.println(this.name + "表演唱歌:" + name);
    }
 
    @Override
    public String dance() {
        System.out.println(this.name + "表演跳舞:魅力四射!" );
        return "谢谢!谢谢!";
    }
}

ProxyUtil

package com.itheima.demo4proxy;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
/**
 * 代理工具类:中介公司,专门负责创建代理对象并返回给别人使用
 */
public class ProxyUtil {
    // 创建一个明星对象的代理对象返回。
    public static StarService createProxy(Star s){
        /**
         * 参数一:用于执行用哪个类加载器去加载生成的代理类。
         * 参数二:用于指定代理类需要实现的接口: 明星类实现了哪些接口,代理类就实现哪些接口
         * 参数三:用于指定代理类需要如何去代理(代理要做的事情)。
         */
        StarService proxy = (StarService) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
                s.getClass().getInterfaces(), new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // 用来声明代理对象要干的事情。
                        // 参数一: proxy接收到代理对象本身(暂时用处不大)
                        // 参数二: method代表正在被代理的方法
                        // 参数三: args代表正在被代理的方法的参数
                        String methodName = method.getName();
                        if("sing".equals(methodName)){
                            System.out.println("准备话筒,收钱20万!");
                        }else if("dance".equals(methodName)){
                            System.out.println("准备场地,收钱100万!");
                        }
                        // 真正干活(把真正的明星对象叫过来正式干活)
                        // 找真正的明星对象来执行被代理的行为:method方法
                        Object result = method.invoke(s, args);
                        return result;
                    }
                });
        return proxy;
    }
}

Test.java

package com.itheima.demo4proxy;
 
import java.lang.reflect.Proxy;
 
public class Test {
    public static void main(String[] args) {
        // 目标:创建代理对象。
        // 1、准备一个明星对象:设计明星类。
        Star star = new Star("章若楠");
        // 2、为章若楠创建一个专属与她的代理对象。
        StarService proxy = ProxyUtil.createProxy(star);
        proxy.sing("《红昭愿》");
        System.out.println(proxy.dance());
    }
}

proxy 变量的类型是 StarService 接口,但它指向的是 实现了该接口的动态代理实例。正因为这个实例是接口的实现类,
所以可以调用接口中定义的 sing() 和 dance() 方法,而方法的具体逻辑由动态代理类和 InvocationHandler 共同实现。
这就是动态代理的核心:通过接口生成代理对象,代理对象既遵守接口规范,又能在方法调用前后插入额外逻辑。

image

posted @ 2025-10-24 11:55  under_world  阅读(3)  评论(0)    收藏  举报