验证中...
开源中国 2018 年度最后一场技术盛会邀你来约~错过就要等明年啦!点此立即预约
片段 1 片段 2 片段 3 片段 4 片段 5
Sth.java
原始数据 复制代码
package com.demo.springbootdemo.proxycommon;
public interface Sth {
void output();
}
RealThing.java
原始数据 复制代码
package com.demo.springbootdemo.proxycommon;
public class RealThing implements Sth {
@Override
public void output() {
System.out.println("real thing");
}
}
Client.java
原始数据 复制代码
package com.demo.springbootdemo.proxycommon;
import com.demo.springbootdemo.dynamicproxy.DynamicProxy;
import com.demo.springbootdemo.staticproxy.StaticProxy;
import java.lang.reflect.Proxy;
public class Client {
public static void main(String[] args) {
/**
* 静态代理,和jdk动态代理的区别,
* StaticProxy作为一个代理类,它是需要实现Sth接口的,如果Sth接口有100个方法呢?
* 它需要全部实现这么多方法吗?显然不合理。
* 而动态代理,首先它需要实现一个jdk提供的接口,并重写该接口的方法,
* 在该方法中通过反射机制来调用目标方法。
* 动态代理的优势就明显了,它不需要去实现Sth接口,它和Sth直接耦合度是很低的
*/
//下面这样做可以把代理类的class文件输出到项目中
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
staticProxy();
dynamicProxy();
System.out.println("END");
}
public static void staticProxy() {
Sth sth = new StaticProxy(new RealThing());
sth.output();
}
public static void dynamicProxy() {
/**
* 动态代理的底层原理是,jvm会生成一个继承Proxy的子类,就叫ProxySon,并且它实现了接口Sth,且重写所有方法,
* 那么方法体是什么?
* 方法体中会写super.h.invoke(...),h是Proxy中的属性InvocationHandler h,此时h有个实现类,
* 就是DynamicProxy,它重写了invoke(),所以ProxySon方法体,实际上调用了DynamicProxy的invoke()
*/
Sth sth = (Sth) Proxy.newProxyInstance(Client.class.getClassLoader(),
new Class[]{Sth.class},new DynamicProxy(new RealThing()));
sth.output();
System.out.println("END");
}
}
DynamicProxy.java
原始数据 复制代码
package com.demo.springbootdemo.dynamicproxy;
import com.demo.springbootdemo.proxycommon.RealThing;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicProxy implements InvocationHandler {
private RealThing realSth;
public DynamicProxy(RealThing realSth) {
this.realSth = realSth;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("DynamicProxy invoke()");
Object result = null;
try {
result = method.invoke(realSth,args);
}catch (Exception e){
System.out.println("error info=" + e.getMessage());
throw e;
}
return result;
}
}
StaticProxy.java
原始数据 复制代码
package com.demo.springbootdemo.staticproxy;
import com.demo.springbootdemo.proxycommon.RealThing;
import com.demo.springbootdemo.proxycommon.Sth;
public class StaticProxy implements Sth {
private RealThing realSth;
public StaticProxy(RealThing realSth) {
this.realSth = realSth;
}
@Override
public void output() {
System.out.println("StaticProxy invoking RealThing");
realSth.output();
}
}

评论列表( 1 )

Damon 2018-12-11 11:52

jdk动态代理和cglib的区别: jdk的方式必须要求目标类实现接口,代理类是继承jdk的Proxy类的; cglib不能代理static和final修饰的类,且代理类是继承目标类的。

你可以在登录后,发表评论

搜索帮助