静态代理&动态代理

静态代理

静态代理使用场景

在实际使用中,经常会遇到一些场景:想在多方法前或方法后加一个共同的方法,如在方法执行前后打印日志、在方法执行完成发送消息通知等。这个时候,我们可以在方法前后调用公用方法,也可以使用代理实现,当然,代理的作用不止如此,这里不做赘述,实现方法如下:

实现方法

先创建一个接口

public interface TestInterface {

    void showMessage();
}

创建一个具体的类,实现这个接口,再创建一个代理类,也实现这个接口

代理类加一个有参构造方法,创建代理类对象的时候传具体类对象即可

// 具体类
public class TestImpl implements TestInterface {

    @Override
    public void showMessage() {
        System.out.println("message");
    }
}

// 代理类
class TestProxy implements TestInterface {

    private TestInterface testInterface;

    public TestProxy(TestInterface testInterface) {
        this.testInterface = testInterface;
    }

    @Override
    public void showMessage() {
        printLogBefore();
        testInterface.showMessage();
        printLogAfter();
    }

    private void printLogBefore() {
        System.out.println("logger before");
    }

    private void printLogAfter() {
        System.out.println("logger after");
    }
}

调用代理类

public static void main(String[] args) throws Exception {
        TestProxy t = new TestProxy(new TestImpl());
        t.showMessage();
    }

执行结果

logger before
message
logger after

JDK动态代理

静态代理的具体类与代理类的对应关系是一对一,那么动态代理可以理解为多对多

动态代理是通过反射实现的

实现方法:

 先创建一个接口

public interface TestInterface {

    void showMessage();
}

创建一个具体的类,实现这个接口,再创建一个代理类,这里与静态代理不同,动态代理的代理类实现的是java.lang.reflect.InvocationHandler接口

被代理类

public class TestImpl implements TestInterface {

    @Override
    public void showMessage() {
        System.out.println("show message");
    }
}

代理类

public class TestProxy<T> implements InvocationHandler {

    private T obj;

    public T build(T obj) {
        this.obj = obj;
        return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        printLogBefore();
        method.invoke(obj, args);
        printLogAfter();
        return null;
    }

    private void printLogBefore() {
        System.out.println("print log before");
    }

    private void printLogAfter() {
        System.out.println("print log after");
    }
}

调用方法

public static void main(String[] args) {
        TestInterface t = new TestProxy<TestInterface>().build(new TestImpl());
        t.showMessage();
    }

返回结果

print log before
show message
print log after

 静态代理与动态代理的区别

  • 静态代理是在编译时已经创建好的,动态代理是在程序运行过程中通过反射创建的
  • 静态代理在运行前就知道是代理哪个类,而动态代理需要在运行的时候才能确定
  • 静态代理通常只代理一个类,而动态代理可以代理接口下所有类

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值