面向接口的静态代理和java动态代理

一、静态代理

/**
 * @Description 代理模式  将要代理对象的接口包装进来,在相同的方法处理中加入其他操作且不影响原先业务
 * @Date 2021-02-16 13:53
 */
//接口
interface Interface{
    void doSomething();
    void somethingElse(String arg);
}
//实际对象
class RealObject implements Interface{

    @Override
    public void doSomething() {
        System.out.println("real doSomething");
    }

    @Override
    public void somethingElse(String arg) {
        System.out.println("real somethingElse "+arg);
    }
}
//代理器继承相同的接口,且把接口装进来(为了装实际对象)
class SimpleProxy implements Interface{
    private Interface proxied;
    public SimpleProxy(Interface proxied){ //通过构造器把接口包装进来
        this.proxied = proxied;
    }
    @Override
    public void doSomething() { //在不影响原业务逻辑的情况下,相同方法中进行更多操作
        //执行前
        System.out.println("SimpleProxy dosomething");
        //实际对象方法
        proxied.doSomething();
        //执行后
        System.out.println("SimpleProxy dosomething after");
    }

    @Override
    public void somethingElse(String arg) { //在不影响原业务逻辑的情况下,相同方法中进行更多操作
        //执行前
        System.out.println("SimpleProxy somethingElse "+arg);
        //实际对象方法
        proxied.somethingElse(arg);
        //执行后
        System.out.println("SimpleProxy somethingElse after");
    }
}
public class SimpleProxyDemo {
    //consumer方法接收Interface对象,RealObject和SimpleProxy都实现了该接口(多态),所以都可以接收
    public static void consumer(Interface iface){
        //分别执行两个方法
        iface.doSomething();
        iface.somethingElse("biu biu");
    }

    public static void main(String[] args) {
        consumer(new RealObject());//普通调用
        System.out.println(" ====== ");
        consumer(new SimpleProxy(new RealObject()));//代理调用
    }
}

个人简单理解:代理类,就是自己包含目标类(把它作为自己的属性,这跟子类继承父类不同),继承的是和目标类相同的接口,所以实现了相同的方法,在相同的方法中触发相应的目标方法(这里有点像子类super()),在方法中增加自定义的额外处理。

二、java动态代理

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @Description 动态代理
 * @Date 2021-02-08 15:47
 */
//SimpleProxyDemo类中已有
//interface Interface{
//    void doSomething();
//    void somethingElse(String arg);
//}
//class RealObject implements Interface{
//
//    @Override
//    public void doSomething() {
//        System.out.println("real doSomething");
//    }
//
//    @Override
//    public void somethingElse(String arg) {
//        System.out.println("real somethingElse "+arg);
//    }
//}
class DynamicProxyHandler implements InvocationHandler {
    private Object proxied;

    public DynamicProxyHandler(Object proxied) {
        this.proxied = proxied;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("*** proxy: " + proxy.getClass() + ", method: " + method + ", args: " + args);
        if (args != null) {
            for (Object arg : args) {
                System.out.println("  " + arg);
            }
        }
        //可以对method直接进行判断需不需要执行 return null
        return method.invoke(proxied, args); //注意是proxied,不是传入的proxy
        //可以在invoke前和后做其他想做的事 写法稍做修改
        //sout();
        // obj = invoke();
        //sout();
        // return obj;
    }
}

public class SimpleDynamicProxy {
    public static void consumer(Interface iface) {
        iface.doSomething();
        iface.somethingElse("biu biu");
    }

    public static void main(String[] args) {
        RealObject real = new RealObject();
        consumer(real);//普通调用
        System.out.println("  ==============  ");
        //newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
        // 三个参数分别是类加载器, 代理实现的接口数组, InvocationHandler的一个具体实现
        Interface proxy = (Interface) Proxy.newProxyInstance(Interface.class.getClassLoader(),
                new Class[]{Interface.class}, new DynamicProxyHandler(real));
        consumer(proxy);//动态代理调用
    }
}

请注意 method.invoke使用的是自己的proxied。

动态代理组装:
1、一个目标对象,目标对象继承的接口
2、一个handler对象 继承 InvocationHandler,将目标对象通过构造器包进去
3、通过Proxy.newProxyInstance()创建动态代理,动态代理可以将所有调用重定向到调用处理器(handler对象),newProxyInstance会通过反射去找目标对象继承的接口列表,通过反射执行接口的方法。

spring aop有两种模式一种jdk动态代理(默认),另一种cglib动态代理(类没有接口)

部分学习文章

个人感受:静态代理是有一个代理类,直接在代理方法中写好处理逻辑;动态代理则是Proxy和InvocationHandler,执行靠反射,通过继承接口找到方法,通过invoke执行。两者都是面向接口的

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值