Java 动态代理
程序员文章站
2022-06-09 21:39:45
...
动态代理是一种运行期动态生成字节码的手段,除此之外生成字节码的手段还有诸如JSP编译器,编译时植入的AOP框架等,这里不做过多的赘述。相信即使是没有使用过动态代理,那么也应该用过Spring来做过Bean的管理,如果Bean是面向接口编程,那么Spring内部都是通过动态代理来实现对Bean的增强。动态代理中所谓的“动态”,是相对于使用Java代码实际编写了代理类的“静态”代理而言,它的优势不在于省去了编写静态类的那点代码,而是实现了在原始类与接口还未知的时候,就确定了代理类的代理行为。
上文红色字段便是动态代理区别于静态代理的精髓所在,若想对动态代理有深入的理解,先对静态代理有一个深刻的认识绝对是最优解。下面来看一个静态代理的例子。
public class StaticProxyTest {
public static void main(String[] args) {
Hello origin = new IHello();
StaticProxy proxy = new StaticProxy(origin);
proxy.sayHello();
}
//接口
static interface Hello {
public void sayHello();
}
//被代理类
static class IHello implements Hello {
@Override
public void sayHello() {
System.out.println("I'm Chinese.");
}
}
//静态代理类
static class StaticProxy implements Hello {
//接收一个被代理对象
private Hello origin;
public StaticProxy(Hello origin) {
this.origin = origin;
}
//代理行为
@Override
public void sayHello() {
System.out.println("Hello world.");
origin.sayHello();
}
}
}
静态代理的核心用一句话概括:编写一个代理类,实现与被代理类相同的接口,注入一个被代理对象,在方法重写中实现代理行为。
动态代理的核心依旧是接口、被代理对象、代理行为,只不过用到了其他的手段来实现,过程更加抽象,不关注实际的接口,被代理类,只关注代理行为。从而导致一种代理行为可以作用于千万种被代理类。动态代理需要用到java.lang.reflect.Proxy和java.lang.reflect.InvocationHandler。下面来看一个动态代理的例子。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynamicProxyTest {
public static void main(String[] args) {
//代理对象
Object proxy = new DynamicProxy().bind(new IHello());
((Hello)proxy).sayHello();
}
//接口
static interface Hello {
void sayHello();
}
//被代理类
static class IHello implements Hello {
@Override
public void sayHello() {
System.out.println("I'm Chinese.");
}
}
//InvocationHandler
static class DynamicProxy implements InvocationHandler {
//被代理对象
private Object origin;
//生成代理对象
public Object bind(Object origin) {
this.origin = origin;
return Proxy.newProxyInstance(
//被代理对象的ClassLoader
origin.getClass().getClassLoader(),
//被代理对象所实现的接口
origin.getClass().getInterfaces(),
//handler
this);
}
//代理行为
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Hello world.");
//通过反射执行被代理对象的原方法
return method.invoke(origin, args);
}
}
}
如果被代理类实现了多个接口,那么动态代理便对所有方法实现了相同的代理行为。
上一篇: 动态代理
下一篇: 代理模式——CGLIB动态代理
推荐阅读
-
零基础写Java知乎爬虫之获取知乎编辑推荐内容(3)
-
Java Class.forName()用法和newInstance()方法原理解析
-
18个运维必知的Nginx代理缓存配置技巧(你都掌握了哪些呢)
-
Cannot convert value of type ‘java.lang.String‘ to required type ‘org.apache.ibatis.session.SqlSessi
-
java.lang.IllegalStateException: Cannot convert value of type ‘java.lang.String‘ to required type ‘c
-
聊一聊Java如何接入招行一网通支付功能
-
Java并发编程必备之Future机制
-
Rx_java(7)Rx_java2操作符(throttleFirst、debounce )介绍-防止按钮被重复点击案例
-
JQuery动态给table添加、删除行 改进版_jquery
-
Java 正则表达式学习总结和一些小例子