- 参考:
- JDK动态代理-超详细源码分析:https://blog.csdn.net/Dome_/article/details/82427386
- JDK动态代理实现原理(jdk8):https://blog.csdn.net/yhl_jxy/article/details/80586785
- 作用:使用代理可以让我们不改变实现类某个实际业务逻辑的情况下,让我们对业务逻辑进行一些功能增强
- 静态代理
- 接口a
- 代理类b实现接口a,同时将接口a的具体实现类作为代理类b的构造参数
// 接口
public interface DemoService {
// 打招呼
void sayHello();
// 告别
void sayGoodbye();
}
// 接口的一个实现类
public class DemoImpl implements DemoService {
@Override
public void sayHello() {
System.out.println("你好!");
}
@Override
public void sayGoodbye() {
System.out.println("再见!");
}
}
// 定义一个代理类也实现我们的接口,同时用接口的具体实现类构造我们的代理类
public class DemoProxy implements DemoService {
// 需要被代理的目标实现类
private DemoService targer;
// 构造方法
public DemoProxy(DemoService targer) {
this.targer = targer;
}
@Override
public void sayHello() {
// 增强操作:在实际对象的方法之前加入一些逻辑
System.out.println("说你好之前,我先挥挥手");
// 实际对象的方法
targer.sayHello();
// 增强操作:在实际对象的方法之后加入一些逻辑
System.out.println("说你好之后,我再给你个飞吻");
}
@Override
public void sayGoodbye() {
// 实际对象的方法
targer.sayGoodbye();
}
}
// 1、不使用代理模式时
public class Main {
public static void main(String[] args) {
DemoService demoService = new DemoImpl();
demoService.sayHello();
}
}
输出:
你好!
// 2、使用代理模式时,用代理对象调用目标方法
public class Main {
public static void main(String[] args) {
DemoService demoService = new DemoImpl();
DemoProxy demoProxy = new DemoProxy(demoService);
demoProxy.sayHello();
}
}
输出:
说你好之前,我先挥挥手
你好!
说你好之后,我再给你个飞吻
- 动态代理-JDK动态代理
- 基于反射机制实现,针对接口代理
- 接口a
- 处理器b实现接口 InvocationHandler,同时将接口a的实现类作为处理器b的构造参数
- 利用 Proxy 动态生成 代理类
// 接口
public interface DemoService {
// 打招呼
void sayHello();
// 告别
void sayGoodbye();
}
// 接口的一个实现类
public class DemoImpl implements DemoService {
@Override
public void sayHello() {
System.out.println("你好!");
}
@Override
public void sayGoodbye() {
System.out.println("再见!");
}
}
// 处理器 实现 InvocationHandler 接口
public class DemoInvocationHandler implements InvocationHandler {
// 需要被代理的目标对象
private Object targer;
// 构造方法
public DemoInvocationHandler(Object targer) {
this.targer = targer;
}
// proxy:动态生成的代理类的实例对象
// method:被代理的目标对象要执行的方法对象
// args:被代理的目标对象要执行的方法的参数
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 功能增强:在实际对象的方法之前加入一些逻辑
System.out.println("说你好之前,我先挥挥手");
// 通过这里执行目标对象的方法
Object object = method.invoke(targer,args);
// 功能增强:在实际对象的方法之后加入一些逻辑
System.out.println("说你好之后,我再给你个飞吻");
return object;
}
}
public class Main {
public static void main(String[] args) {
// 目标对象
DemoService demoService = new DemoImpl();
// 目标对象的处理器
DemoInvocationHandler handler = new DemoInvocationHandler(demoService);
// 生成代理对象(1、生成代理类 2、获取代理类的构造方法(将 handler 作为构造参数) 3、通过构造方法创建代理类的实例对象)
DemoService proxy = (DemoService)Proxy.newProxyInstance(handler.getClass().getClassLoader(),demoService.getClass().getInterfaces(),handler);
// 方法调用
proxy.sayHello();
}
}
- 动态代理-CGLIB动态代理
- 基于 ASM 实现,针对类代理,与接口无关
- 原理是对指定目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。