动态代理的分类和各自的实现方式

Posted newcityboy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态代理的分类和各自的实现方式相关的知识,希望对你有一定的参考价值。


package com.hope.cglig;

import com.hope.proxy.IProducer;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

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

/**
* 消费者
* @author newcityman
* @date 2019/11/22 - 12:09
*/
public class Client {
public static void main(String[] args) {
final Producer producer = new Producer();

/**
* 动态代理:
* 特点:字节码随用随创建,随用随加载
* 作用:不修改源码的基础上对方法进行增强
* 分类:
* 基于接口的动态代理
* 基于子类的动态代理
* 基于子类的动态代理
* 涉及的类:Enhancer
* 提供者:第三方cglib库
* 如何创建代理对象:
* 使用enhancer类中的create方法
* 创建代理对象的要求:
* 被代理的类不能是最终类
* enhance类的create方法的参数
* class:字节码
* 它是用于指定被代理对象的字节码
* Callback:用于提供增强代码
* 它是让我们写如何代理,我们的一般都是写一个该接口的实现类,通常情况是匿名内部类,但不是必须的。
* 此接口的实现类都是谁用谁写。
* 我们一般写的都是该接口的子接口实现类:MethodInterceptor
*/
Producer cgligProducer=(Producer) Enhancer.create(producer.getClass(),
new MethodInterceptor() {
/**
* 执行被代理对象的任何方法都会经过该方法
* @param proxy
* @param method
* @param args
* @param methodProxy
* @return
* @throws Throwable
*/
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//提供增强的代码
Object rtValue=null;
//1、获取方法执行的参数
Float money=(Float)args[0];
//2、判断当前的方法名称是不是销售
if("saleProduce".equals(method.getName())){
rtValue=method.invoke(producer,money*0.5f);
}
return rtValue;
}
});
cgligProducer.saleProduce(12000f);
}
}


package com.hope.proxy;

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

/**
* 消费者
*
* @author newcityman
* @date 2019/11/22 - 12:09
*/
public class Client {
public static void main(String[] args) {
final Producer producer = new Producer();

/**
* 动态代理:
* 特点:字节码随用随创建,随用随加载
* 作用:不修改源码的基础上对方法进行增强
* 分类:
* 基于接口的动态代理
* 基于子类的动态代理
* 基于接口的动态代理
* 涉及的类:proxy
* 提供者:jdk官方
* 如何创建代理对象:
* 使用proxy类中的newProxyInstance方法
* 创建代理对象的要求:
* 被代理的类必须至少实现一个接口,如果没有则不能使用
* newProxyInstance方法的参数
* ClassLoader:类加载器
* 它是用于加载代理对象的字节码的,和被代理对象使用相同的类加载器。
* class[]:字节码数组
* 它适用于让代理对象和被代理对象有相同的方法
* InvocationHandler:用于提供增强代码
* 它是让我们写如何代理,我们的一般都是写一个该接口的实现类,通常情况是匿名内部类,但不是必须的。
* 此接口的实现类都是谁用谁写。
*
*/
IProducer proxyProducer = (IProducer) Proxy.newProxyInstance(producer.getClass().getClassLoader(),
producer.getClass().getInterfaces(),
new InvocationHandler() {
/**
* 作用:执行被代理对象的任何接口方法都会经过该方法
* @param proxy
* @param method
* @param args
* @return
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//提供增强的代码
Object rtValue = null;
//1、获取方法执行的参数
Float money = (Float) args[0];
if ("saleProduce".equals(method.getName())) {
rtValue = method.invoke(producer, money * 0.8f);
}
return rtValue;
}
});
proxyProducer.saleProduce(10000f);
}
}
 

以上是关于动态代理的分类和各自的实现方式的主要内容,如果未能解决你的问题,请参考以下文章

Java面试-动态代理

反射机制-动态代理

Java动态代理实现方式一

Java设计模式——代理模式

Java设计模式——代理模式

Spring代理模式,AOP