JAVA代理

仅作为个人学习笔记

1. 代理模式

使用代理对象代替对真实对象的访问,达到在不修改源代码的前提下实现功能的扩展

2. 静态代理

静态代理在编译时将接口、实现类、代理变成实际的class文件

2.1 静态代理实现步骤

(1)定义一个接口及其实现类(目标类)
(2)定义一个代理类,实现该接口
(3)将目标对象注入代理类、然后在代理类的对应方法调用目标类中的对应方法。
在代理类的对应方法中屏蔽对目标类的直接访问,并实现在执行目标类对应方法前后功能的扩展

定义接口与其实现类

//生产衣服接口
public interface ClothFactory {
    int produce();
}

public class ClothFactoryNike implements ClothFactory{
    @Override
    public int produce() {
        System.out.println("生产Nike");
        return 0;
    }
}

定义代理类

public class NikeProxy implements ClothFactory{

    private ClothFactory clothFactory;
    public NikeProxy(ClothFactoryNike clothFactoryNike) {
        this.clothFactory = clothFactoryNike;
    }

    @Override
    public int produce() {
        System.out.println("前置功能增强");
        int res = clothFactory.produce();
        System.out.println("后置功能增强");
        return res;
    }
}

使用静态代理

public class NikeTest {

    @Test
    public void test(){
        ClothFactory  clothFactory = new ClothFactoryNike();
        NikeProxy nikeProxy = new NikeProxy(clothFactory);
        nikeProxy.produce();
    }
}

3. 动态代理

动态代理不需要对每个目标类都单独创建一个代理类,也不需要我们必须实现接口,是在运行时动态生成类字节码,并加载到JVM中。
动态代理包括CGLIB和JDK动态代理

3.1JDK动态代理

核心:InvocationHandler 接口和 Proxy 类
其中,Proxy类中的核心方法是newProxyInstance(),用来生产代理对象
参数包括 类加载器loader、被代理类实现的接口interfaces和实现InvocationHandler接口的对象handler

    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
    	...
    }

JDK动态代理步骤:
1、创建被代理类的接口及其实现类
2、自定义InvocationHandler接口的实现类,重写其中的invoke方法
3、通过Proxy.newProxyInstance方法创建代理对象

//被代理接口
public interface ClothFactory {
    int produce();
}
//被代理接口的实现类
public class ClothFactoryNike implements ClothFactory{
    @Override
    public int produce() {
        System.out.println("生产Nike");
        return 0;
    }
}
//定义一个Handler接口实现类,重写invoke方法
public class NikeProxy1 implements InvocationHandler {
    private Object obj;
    public NikeProxy1(Object obj) {
        this.obj = obj;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(method.getName()+"的前置增强");
        Object res = method.invoke(obj,args);
        System.out.println(method.getName()+"的后置增强");
        return res;
    }
}
//定义一个代理工厂,用来获取代理类的实例对象
public class NikeProxyFactory {
    public static Object getProxyInstance(Object target){
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),new NikeProxy1(target));
    }
}

//测试
@Test
public void test1(){
    ClothFactoryNike clothFactoryNike = new ClothFactoryNike();
    ClothFactory instance = (ClothFactory) NikeProxyFactory.getProxyInstance(clothFactoryNike);
    instance.produce();
}

然而,JDL代理类只能代理接口或者实现接口的类,对于为实现接口的类无法代理。

3.2 CGLIB动态代理

代理对象在底层创建了一个子类进行逻辑增强。
核心: MethodInterceptor 接口和 Enhancer 类
其中,MethodInterceptor 接口中的interceptor用于拦截并增强被代理类,类似于JDK代理中的invoke方法

public interface MethodInterceptor
extends Callback{
    // 拦截被代理类中的方法
    public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args,MethodProxy proxy) throws Throwable;
}

CGLIB动态代理的使用步骤
1、定义一个类
2、创建一个实现MethodInterceptor接口的类
3、通过Enhancer类的create()方法创建代理类

//定义被代理类
public class AdidasFactory {
    public void produce(){
        System.out.println("生产Adidas服饰");
    }
}

//定义MethodInterceptor接口实现类
public class AdidasProxy implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println(method.getName()+"的前置方法");
        Object res = methodProxy.invokeSuper(o, objects);
        System.out.println(method.getName()+"的后置方法");
        return res;
    }
}
//定义代理工厂,用于获取代理示例
public class AdidasProxyFactory {
    public static Object getProxy(Class<?> clazz){
    	//动态代理增强类
        Enhancer enhancer = new Enhancer();
        //设置类加载器
        enhancer.setClassLoader(clazz.getClassLoader());
        //设置被代理类
        enhancer.setSuperclass(clazz);
        //设置方法拦截
        enhancer.setCallback(new AdidasProxy());
        //创建代理类对象
        return enhancer.create();
    }
}
//测试
@Test
public void cgProxy(){
    AdidasFactory adidasFactory1 = (AdidasFactory) AdidasProxyFactory.getProxy(AdidasFactory.class);
    adidasFactory1.produce();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值