验证中...
Sth.java
Raw Copy
package com.demo.springbootdemo.proxycommon;
public interface Sth {
void output();
}
RealThing.java
Raw Copy
package com.demo.springbootdemo.proxycommon;
public class RealThing implements Sth {
@Override
public void output() {
System.out.println("real thing");
}
}
Client.java
Raw Copy
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
Raw Copy
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
Raw Copy
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();
}
}

Comment list( 2 )

/damongit 2018-12-26 17:44

jdk动态代理,需要一个jdk提供的Proxy类,需要一个实现InvocationHandler的实现类,需要一个目标接口以及其实现类。
jvm会生成一个继承Proxy的类,并且实现目标接口,然后重写目标接口中的所有方法,各方法体中会调用父类Proxy的成员变量,
也就是InvocationHandler,然后调用其方法invoke(),那么InvocationHandler接口是有实现类的,第一行说了的,所有实际上调用的就是
该实现类的invoke()。在通过目标接口调用了某方法之后,才会通过invoke()去调用接口实现类的方法。

/damongit 2018-12-11 11:52

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

You need to Sign in for post a comment

Help Search

Gitee_sixth 5th_float_left_close