JDK 动态代理的原理是利用反射机制,在运行时创建代理类,必要条件是代理对象基于接口实现。
创建一个接口及其实现类。
public interface IService {
void sayHello();
}public class JdkServiceImpl implements IService {
@Override
public void sayHello() {
System.out.println("Hello JAVA Proxy");
}
}创建代理处理类,必须实现 InvocationHandler 接口。
@AllArgsConstructor
public class ServiceInvocationHandler implements InvocationHandler {
private final Object target;
@Override
public Object invoke(Object obj, Method method, Object[] args) throws Throwable {
System.out.println("-------- begin ----------");
Object result = method.invoke(target, args);
System.out.println("-------- end ----------");
return result;
}
}执行动态代理
public class JdkProxyTest {
public static void main(String[] args) {
IService service = new JdkServiceImpl();
ServiceInvocationHandler handler = new ServiceInvocationHandler(service);
IService proxy = (IService) Proxy.newProxyInstance(JdkProxyTest.class.getClassLoader(), new Class[]{IService.class}, handler);
proxy.sayHello();
System.out.println();
System.out.println(proxy.getClass().getSimpleName() +
" extend " + proxy.getClass().getSuperclass().getSimpleName() +
" implements " + Arrays.stream(proxy.getClass().getInterfaces())
.map(Class::getSimpleName)
.collect(Collectors.joining(",")));
}
}输出结果如下,可以看出在 sayHello 方法前后,执行了代理处理类中的代码输出,说明通过 JDK 动态代理实现了代理增强。
-------- begin ----------
Hello JAVA Proxy
-------- end ----------
$Proxy0 extend Proxy implements IService最后一行的输出显示了动态生成的代理类的继承关系,该类实现代理对象的接口,JDK 动态代理的继承机制决定了只能对接口进行代理。
Cglib 动态代理的原理是利用字节码技术,在运行时创建一个继承代理类的 class,所以代理对象不需要实现接口,但要求被代理类及方法必须不是 final 的
创建一个需要被代理的类
public class CglibServiceImpl {
public void sayHello() {
System.out.println("Hello Cglib Proxy");
}
}创建方法拦截器,必须实现 MethodInterceptor 接口,实现代理增强
public class ServiceInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] params, MethodProxy methodProxy) throws Throwable {
System.out.println("-------- begin ----------");
Object result = methodProxy.invokeSuper(obj, params);
System.out.println("-------- end ----------");
return result;
}
}执行代理操作
public class CglibProxyTest {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(CglibServiceImpl.class);
enhancer.setCallback(new ServiceInterceptor());
CglibServiceImpl proxy = (CglibServiceImpl) enhancer.create();
proxy.sayHello();
System.out.println();
System.out.println(proxy.getClass().getSimpleName() +
" extend " + proxy.getClass().getSuperclass().getSimpleName() +
" implements " + Arrays.stream(proxy.getClass().getInterfaces())
.map(Class::getSimpleName)
.collect(Collectors.joining(",")));
}
}输出结果如下
-------- begin ----------
Hello Cglib Proxy
-------- end ----------
ServiceImpl$EnhancerByCGLIB$ef25c05 extend ServiceImpl implements FactorySpring 也提供了自己动态代理实现,但其实做的还是整合的工作,底层依然是基于上文中的两种技术。
创建方法拦截器,需要实现 MethodInterceptor 接口(这个接口在 org.aopalliance.intercept 包中,与 cglib 中的不是同一个)。
public class AopInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("-------- begin ----------");
Object result = invocation.proceed();
System.out.println("-------- end ----------");
return result;
}
}执行代理操作
public class SpringProxyTest {
public static void main(String[] args) {
executeJdkProxy();
// executeCglibProxy();
}
public static void executeJdkProxy() {
ProxyFactory factory = new ProxyFactory();
factory.setInterfaces(IService.class);
factory.setTarget(new JdkServiceImpl());
factory.addAdvice(new AopInteceptor());
IService proxy = (IService) factory.getProxy();
proxy.sayHello();
printClassName(proxy);
}
public static void executeCglibProxy() {
ProxyFactory factory1 = new ProxyFactory();
factory1.setTarget(new CglibServiceImpl());
factory1.addAdvice(new AopInteceptor());
CglibServiceImpl proxy1 = (CglibServiceImpl) factory1.getProxy();
proxy1.sayHello();
printClassName(proxy1);
}
public static void printClassName(Object proxy) {
System.out.println();
System.out.println(proxy.getClass().getSimpleName() +
" extend " + proxy.getClass().getSuperclass().getSimpleName() +
" implements " + Arrays.stream(proxy.getClass().getInterfaces())
.map(Class::getSimpleName)
.collect(Collectors.joining(",")));
}
}执行 executeJdkProxy 方法输出
-------- begin ----------
Hello World
-------- end ----------
$Proxy18 extend Proxy implements IService,SpringProxy,Advised,DecoratingProxy执行 executeCglibProxy 方法输出
-------- begin ----------
Hello Cglib Proxy
-------- end ----------
CglibServiceImpl$EnhancerBySpringCGLIB$57b39275 extend CglibServiceImpl implements SpringProxy,Advised,Factory通过最后输出的类继承结构可以看出在 ProxyFactory 之下的实现原理,executeJdkProxy 与 executeCglibProxy 方法不同的一点是调用 factory.setInterfaces 设置了接口,如果不设置接口,那么底层还是使用 cglib 实现,虽然最终呈现出来的效果是一样的。所以具体使用哪种方案实现,并不处决了代理对象是不是接口,而是有没有向 ProxyFactory 设置接口(当然设置接口的前提首先得实现接口)。
根据方法 getProxy 进行源码跟踪
public class ProxyFactory extends ProxyCreatorSupport {
public Object getProxy() {
return createAopProxy().getProxy();
}
}createAopProxy 方法在其父类中实现,调用 AopProxyFactory.createAopProxy 方法创建一个 AopProxy 对象,AopProxyFactory 默认使用 DefaultAopProxyFactory。
public class ProxyCreatorSupport extends AdvisedSupport {
private AopProxyFactory aopProxyFactory;
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
}在 DefaultAopProxyFactory 的 createAopProxy 方法,可以看到根据不同的条件会选择创建不同的 AopProxy。
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
} else {
return new JdkDynamicAopProxy(config);
}
}
}AopProxy 的实现类分别代表不同的实现策略
以 JdkDynamicAopProxy 的实现为例,可以看到最终调用的还是 JDK 提供的 Proxy.newProxyInstance() 方法创建代理对象。
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
public Object getProxy() {
return getProxy(ClassUtils.getDefaultClassLoader());
}
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
Class>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
} 版权声明:我们致力于保护作者版权,注重分享,被刊用文章【jdk动态代理实现原理(JDK)】因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!;
工作时间:8:00-18:00
客服电话
电子邮件
beimuxi@protonmail.com
扫码二维码
获取最新动态
