动态代理·步骤:
1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法
package com.qcby.demo.proxyaop.proxy.jdk;
import com.qcby.demo.proxyaop.proxy.star.JiaLing;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @className: AdvertisementHandler
* @description: 广告代理类
* @author: lxt
* @create: 2021-05-12 15:30
**/
@Slf4j
public class AdvertisementHandler implements InvocationHandler {
private Object object;
/**
* 代理对象的逻辑:
* 前置或后置或都增强我们的代理对象(比如aop:token验证、重复提交验证、操作日志)
* 代替目标对象:mybatis mapper层
*/
// 经纪人和贾玲建立关系
public AdvertisementHandler(Object object) {
this.object = object;
}
// 覆写接口的方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log.info("贾玲的代理正在与您沟通【广告代言】...");
// method.invoke(object,args);
log.info("贾玲的代理正在完成收尾【广告代言】...");
return null;
}
}
2.创建被代理的类以及接口
需要动态代理的接口
package com.qcby.demo.proxyaop.proxy.star;
/**
* 广告接口
*/
public interface IAdvertisement {
/**
* 代言方法
*/
void display();
String displayRe();
}
需要动态代理·的目标对象
package com.qcby.demo.proxyaop.proxy.star;
import lombok.extern.slf4j.Slf4j;
/**
* 贾玲
*
* lombok
*/
@Slf4j
public class JiaLing implements IAdvertisement {
@Override
public void display() {
log.info("大家好!我是贾玲!");
}
@Override
public String displayRe() {
log.info("大家好!我是贾玲Re!");
return "success!";
}
}
3.通过Proxy的静态方法
newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理
//因为JDK为我们生成的动态代理对象也会去实现真实对象实现了的所有的接口
//所以此处我们可以直接使用Advertisement接口来接受JDK动态代理生成的代理对象【经纪人】
//产生代理对象的方法
IAdvertisement advertisement = (IAdvertisement) Proxy.newProxyInstance(
jiaLing.getClass().getClassLoader()
, jiaLing.getClass().getInterfaces()
,advertisementHandler
);
4.通过代理调用方法
package com.qcby.demo.proxyaop.proxy.jdk;
import com.qcby.demo.proxyaop.proxy.star.JiaLing;
import com.qcby.demo.proxyaop.proxy.star.IAdvertisement;
import sun.misc.ProxyGenerator;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Proxy;
/**
* @className: JdkDynamicProxy
* @description:jdk动态代理
* @author: lxt
* @create: 2021-05-12 15:34
**/
public class JdkDynamicProxy {
public static void main(String[] args) throws IOException {
// 创建目标对象
JiaLing jiaLing = new JiaLing();
// 绑定贾玲和广告代理类的关系
AdvertisementHandler advertisementHandler = new AdvertisementHandler(jiaLing);
//因为JDK为我们生成的动态代理对象也会去实现真实对象实现了的所有的接口
//所以此处我们可以直接使用Advertisement接口来接受JDK动态代理生成的代理对象【经纪人】
//产生代理对象的方法
IAdvertisement advertisement = (IAdvertisement) Proxy.newProxyInstance(
jiaLing.getClass().getClassLoader()
, jiaLing.getClass().getInterfaces()
,advertisementHandler
);
//通过反编译工具可以查看源代码
byte[]bytes= ProxyGenerator.generateProxyClass("$Proxy0",new Class[]{IAdvertisement.class});
// idea 打开字节码文件,可查看动态生成的代理类
String dir = "D:/proxydemo/jdk/";
File file = new File(dir);
if(!file.exists()){
file.mkdirs();
}
FileOutputStream os=new FileOutputStream(dir+"$Proxy0.class");
os.write(bytes);
os.close();
//执行代理对象【经纪人】的display()方法
advertisement.display();
}
}