动态代理
基于JDK的动态代理
基于接口
委托类和代理类实现的公共接口 Subject.java
package com.lvshui5u.test.jdkproxy;
/**
* @author: lvshui5u
* @date: 2021/5/28 10:22
* @describe: 基于jdk的动态代理
*
* 1. 创建一个接口(被代理)
* 2. 实现接口
* 3. 创建代理类,实现InvocationHandler接口
* 4. 代理类的调用,用Proxy类创建实例
*/
public interface Subject {
void hello(String str);
void bye(String str);
}
实现公共接口的具体委托类 SubjectImpl.java
package com.lvshui5u.test.jdkproxy;
/**
* @author: lvshui5u
* @date: 2021/5/28 10:28
* @describe:
*/
public class SubjectImpl implements Subject {
@Override
public void hello(String str) {
System.out.println("hello "+str);
}
@Override
public void bye(String str) {
System.out.println("bye "+str);
}
}
对委托类的处理,实现InvocationHandler接口,具体实现一个invoke方法 SubjectProxy.java
package com.lvshui5u.test.jdkproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @author: lvshui5u
* @date: 2021/5/28 10:30
* @describe:
*/
public class SubjectProxy implements InvocationHandler {
private Subject subject;
public SubjectProxy(Subject subject) {
this.subject = subject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("--- start ---");
// 利用反射调用类里面的实际方法
Object invoke = method.invoke(subject, args);
System.out.println("--- end ---");
return invoke;
}
}
代理类的实现,调用Proxy类的newProxyInstance方法
package com.lvshui5u.test.jdkproxy;
import java.lang.reflect.Proxy;
/**
* @author: lvshui5u
* @date: 2021/5/28 10:35
* @describe:
*/
public class SubjectMain {
public static void main(String[] args) {
Subject subject = new SubjectImpl();
SubjectProxy subjectProxy = new SubjectProxy(subject);
// 代理类的类加载器 被代理类的接口(们) 代理类实例
Subject instance = (Subject) Proxy.newProxyInstance(subjectProxy.getClass().getClassLoader(),
subject.getClass().getInterfaces(),
subjectProxy);
instance.hello("world");
instance.bye("world");
}
}
输出
--- start ---
hello world
--- end ---
--- start ---
bye world
--- end ---
基于CGLIB的动态代理
基于继承,原理是对代理的目标类生成一个子类,并覆盖其中方法实现增强。
委托类 Subject.java
package com.lvshui5u.test.cglibproxy;
/**
* @author: lvshui5u
* @date: 2021/5/28 10:55
* @describe: 基于cglib的动态代理
*
* 1. 创建被代理类
* 2. 创建方法拦截器,实现MethodInterceptor接口
* 3. 用Enhancer 生成被代理类
*/
public class Subject {
public void hello(String str){
System.out.println("hello " +str);
}
public void bye (String str){
System.out.println("bye " +str);
}
}
方法拦截器,实现MethodInterceptor接口,对方法进行拦截并增强
package com.lvshui5u.test.cglibproxy;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @author: lvshui5u
* @date: 2021/5/28 10:56
* @describe:
*/
public class SubjectInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("--- start ---");
Object invoke = methodProxy.invokeSuper(o, objects);
System.out.println("--- end ---");
return invoke;
}
}
创建增强器,增强器创建代理类
package com.lvshui5u.test.cglibproxy;
import net.sf.cglib.proxy.Enhancer;
/**
* @author: lvshui5u
* @date: 2021/5/28 11:08
* @describe:
*/
public class SubjectMain {
public static void main(String[] args) {
// 增强器
Enhancer enhancer = new Enhancer();
// 指定代理类
enhancer.setSuperclass(Subject.class);
// 设置回调,对于代理类上所有方法的调用,会调用callback,callback实现需要interceptor()
enhancer.setCallback(new SubjectInterceptor());
Subject subject = (Subject) enhancer.create();
subject.hello("world");
subject.bye("world");
}
}
输出
--- start ---
hello world
--- end ---
--- start ---
bye world
--- end ---