Java静态代理与动态代理

微信搜索关注“咖啡遇上代码”公众号,查看更多

Java代理分为静态代理与动态代理,其中动态代理又包括jdk动态代理、cglib动态代理以及其他的动态代理(本文只介绍jdk动态代理和cglib动态代理)。

静态代理

代理类通过实现与被代理类相同的接口,在代理类中维护一个被代理对象。通过构造器或set等方法注入被代理对象,然后通过执行代理对象实现的接口方法来调用被代理对象实现的接口方法(代理对象实现的方法中可添加相应的业务功能)。

代码示例

公共接口

public interface HelloService {
    public void say(String name);
}

目标类(被代理类)

public class HelloServiceImpl implements HelloService {
    @Override
    public void say(String name) {
        System.out.println("hello " + name);
    }
}

代理类

public class HelloServiceProxy implements HelloService {

    private HelloService helloService;

    public HelloServiceProxy(HelloService helloService) {
        this.helloService = helloService;
    }
    @Override
    public void say(String name) {
        before();
        helloService.say(name);
        after();
    }
    private void before() {
        System.out.println("调用say方法之前...");
    }
    private void after() {
        System.out.println("调用say方法之后...");
    }
}

测试类

public class MainTest {

    public static void main(String[] args) {
        HelloServiceProxy proxy = new HelloServiceProxy(new HelloServiceImpl());
        proxy.say("world");
    }

}

测试结果

调用say方法之前…
hello world
调用say方法之后…

动态代理

JDK代理

JDK代理是根据被代理类对象,动态地创建了一个代理类,通过该代理类对象进行方法调用,或者说通过接口中的方法名,在动态生成的代理类中调用业务实现类的同名方法。

代码示例

被代理类接口

public interface HelloService {
    public void say(String name);
}

目标类(被代理类)

public class HelloServiceImpl implements HelloService {

    @Override
    public void say(String name) {
        System.out.println("hello " + name);
    }
}

代理类

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkProxy implements InvocationHandler {

    private Object target = null;

    /**
     * 建立代理对象和被代理对象的代理关系,并返回代理对象
     * @param target 被代理对象
     * @return 返回代理对象
     */
    public Object bind(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    /**
     * 代理方法处理逻辑
     * @param proxy 代理对象
     * @param method 方法
     * @param args 方法参数
     * @return 返回代理的结果
     * @throws Throwable 异常
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        //执行目标对象的方法
        Object obj = method.invoke(target, args);
        after();
        return obj;
    }

    private void before() {
        System.out.println("调用被代理对象之前...");
    }

    private void after() {
        System.out.println("调用被代理对象之后...");
    }

}

测试类

public class MainTest {
    public static void main(String args[]) {
        JdkProxy jdk = new JdkProxy();
        //获取代理对象
        HelloService proxy = (HelloService) jdk.bind(new HelloServiceImpl());
        //执行代理对象的方法
        proxy.say("Amy");
    }
}

测试结果:

调用被代理对象之前…
hello Amy
调用被代理对象之后…

Cglib代理

Cglib代理是通过继承业务类来构建一个子类对象,来实现对目标(被代理)对象的业务拓展。

代码示例

目标类(被代理类)

public class HelloService {
    public void say(String name) {
        System.out.println("hello " + name);
    }
}

代理类

import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CglibProxy implements MethodInterceptor {

    private Object target;

    public CglibProxy(Object target) {
        this.target = target;
    }

    /**
     * 生成Cglib代理对象
     * @return 创建的代理对象
     */
    public Object getProxy() {
        //工具类
        Enhancer enhancer = new Enhancer();
        //设置父类
        enhancer.setSuperclass(target.getClass());
        //设置回调函数
        enhancer.setCallback(this);
        //创建代理对象
        return enhancer.create();
    }

    /**
     * 代理方法处理逻辑
     * @param proxy 代理对象
     * @param method 方法
     * @param args 方法参数
     * @param methodProxy 方法代理
     * @return 返回代理的结果
     * @throws Throwable 异常
     */
    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        before();
        //执行目标对象的方法
        Object result = method.invoke(target, args);
//        Object result = methodProxy.invokeSuper(proxy, args);
        after();
        return result;
    }

    private void before() {
        System.out.println("调用被代理对象之前...");
    }

    private void after() {
        System.out.println("调用被代理对象之后...");
    }
}

测试类:

public class MainTest {
    public static void main(String args[]) {
        CglibProxy cglib = new CglibProxy(new HelloService());
        //获取代理对象
        HelloService proxy = (HelloService) cglib.getProxy();
        //执行代理对象的方法
        proxy.say("Bob");
    }
}

测试结果

调用被代理对象之前…
hello Bob
调用被代理对象之后…

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值