SDK动态代理

可以实现在其运行时动态添加一个类、实现一个或者多个接口,可以在不修改原有类基础上动态为通过该类获取的对象添加方法、修改行为。
动态代理是实现面向切面的编程AOP的基础。切面例子包含有日志、权限检查、数据库事务等。

一、静态代理

存在价值

  1. 节省成本比较高的实际对象的创建开销,按需延迟加载,创建代理是并不真正创建实际对象,而只是保存实际对象的地址,在需要时再加载或者创建。
  2. 执行权限检查,代理检查权限后,在调用实际对象
  3. 屏蔽网络差异和复杂性,代理在本地,而实际对象在其他服务器上,调用本地代理,本地代理请求其他服务器

在这里插入图片描述

demo

public class SimpleStaticProxyDemo {
    static interface IService{//共同接口
        public void sayHello();
    }
    static class RealService implements IService{//实际对象
        @Override
        public void sayHello() {
            System.out.println ("hello");
        }
    }

    static class TraceProxy implements IService{//代理
        private IService realService;//定义成员变量
        public TraceProxy(IService realService){//将成员变量指向实际对象,并在构造方法中初始化
            this.realService = realService;
        }

        @Override
        public void sayHello() {
            System.out.println ("entering sayHello");
            this.realService.sayHello ();
            System.out.println ("leaving sayHello");
        }
    }

    public static void main(String[] args) {
        RealService realService = new RealService ();
        TraceProxy traceProxy = new TraceProxy ( realService );
        traceProxy.sayHello ();
    }
}

//输出结果
entering sayHello
hello
leaving sayHello

二、动态代理

优点

可以编写通用的代理逻辑,用于各种类型的被代理对象,而不需要为每个被代理的类型都创建一个静态代理类。

与静态代理差异

与静态的区别在于代理对象ProxyService的创建方式变了,他是用java.lang.reflect包中的Proxy类的静态方法newProxyInstance来创建代理对象,方法声明为
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h);InvocationHandler中只定义了一个方法invoke();对代理借口所有方法的调用的都会转给该方法。
newProxyInstance的返回值类型为Object,可以强制转换为interfaces数组中的某个接口类型。
demo中强制转换成了IService类型,它不能强制转换为某个类的类型,比如RealService。

在这里插入图片描述

demo

package thread_practice.fanshe;

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

public class GeneralProxyDemo {
    static interface IServiceA {
        public void sayHello();
    }

    static class ServiceAImpl implements IServiceA {
        @Override
        public void sayHello() {
            System.out.println ( "hello" );
        }
    }

    static interface IServiceB {
        public void fly();
    }

    static class ServiceBImpl implements IServiceB {
        @Override
        public void fly() {
            System.out.println ( "flying" );
        }
    }

    static class SimpleInvocationHandle implements InvocationHandler {
        private Object realObj;

        public SimpleInvocationHandle(Object realObj) {
            this.realObj = realObj;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
            System.out.println ( "entering" + realObj.getClass ()
                    .getSimpleName () + ":" + method.getName () );
            Object result = method.invoke ( realObj, args );
            System.out.println ( "leaving" + realObj.getClass ()
                    .getSimpleName () + ":" + method.getName () );
            return result;
        }
    }

    private static <T> T getProxy(Class<T> intf, T realObj) {
        return (T) Proxy.newProxyInstance ( intf.getClassLoader (),
                new Class<?>[]{
                        intf
                }, new SimpleInvocationHandle ( realObj ) );
    }

    public static void main(String[] args) {
        IServiceA a = new ServiceAImpl ();
        IServiceA aProxy = getProxy ( IServiceA.class, a );
        aProxy.sayHello ();
        ServiceBImpl b = new ServiceBImpl ();
        IServiceB bProxy = getProxy ( IServiceB.class, b );
        bProxy.fly ();
    }

}

//输出结果
enteringServiceAImpl:sayHello
hello
leavingServiceAImpl:sayHello
enteringServiceBImpl:fly
flying
leavingServiceBImpl:fly

在这里插入图片描述

三、cglib动态代理

java SDK动态代理的局限在于,它只能为接口创建代理,返回的代理对象也只能转换到某个接口类型。如果希望代理非接口中定义的方法,就可以采用第三方库cglib。

CGLIB详解(最详细)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值