昨晚上敲了个代理的demo(实现了下静态代理,jdk动态代理和cglib代理)。贴出来:
具体代码:
* 接口:IRunner
package dailimoshi;
public interface IRunner {
void run();
}
*实现类Runner
package dailimoshi;
public class Runner implements IRunner{
@Override
public void run() {
System.out.println("运动员正在跑步...");
}
}
*静态代理
静态代理 在编译时期就确定好的。
代理类和被代理类具有相同的接口。
package dailimoshi;
import java.util.Random;
public class StaticRunnerAgent implements IRunner{
private Runner target;
public StaticRunnerAgent(Runner target) {
super();
this.target = target;
}
@Override
public void run() {
Random rand = new Random();
if(rand.nextBoolean()){
System.out.println("运动员代理安排运动员跑步");
target.run();
}else{
System.out.println("运动员代理心情不好,不安排运动员跑了..");
}
}
}
*jdk动态代理
package dailimoshi;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Random;
/**
* 这个是动态代理类
* @author fjf
* 2018年8月21日 16:15:04
*
*
*
*/
public class DynamicRunerAgent {
private IRunner target;
public DynamicRunerAgent(IRunner target) {
super();
this.target = target;
}
public IRunner getProxy(){
IRunner proxy = null;
//获得类加载器 目标类和代理类 都是这个类加载器
//ClassLoader loader = target.getClass().getClassLoader();
ClassLoader loader = IRunner.class.getClassLoader();
//代理对象的接口 和 目标对象的接口是一样的
Class[] interfaces = new Class[]{IRunner.class};
//调用处理器
InvocationHandler h = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
String result =" ";
Random rand = new Random();
if(rand.nextBoolean()){
System.out.println("jdk动态代理--代理人安排运动员跑步 " );
result = (String) method.invoke(target, args);
}else{
System.out.println("动态代理--代理人心情不好,不安排运动员。 " );
}
return result;
}
};
proxy = (IRunner) Proxy.newProxyInstance(loader, interfaces, h);
return proxy;
}
}
*cglib动态代理
package dailimoshi;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
* 使用cglib 来动态代理
* @author fjf
* 2018年8月22日 11:44:55
*/
public class CglibRunnerAgent implements MethodInterceptor {
private Object target; //Cglib需要代理的目标对象
public Object createProxyObject(Object obj) {
this.target = obj;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(obj.getClass());
enhancer.setCallback(this);
Object proxyObj = enhancer.create();
return proxyObj;// 返回代理对象
}
@Override
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
Object obj = null;
System.out.println("动态代理-cglib--代理人安排运动员跑步 " );
obj = method.invoke(target, args);
return obj;
}
}
*Test 测试类
package dailimoshi;
public class Test {
public static void main(String[] args) {
IRunner r = new StaticRunnerAgent(new Runner());
System.out.println("静态代理---有比赛,联系运动员代理");
r.run();
System.out.println("---------------------------------");
System.out.println("jdk动态代理---有比赛,联系运动员代理");
IRunner dr = (IRunner) new DynamicRunerAgent(new Runner()).getProxy();
dr.run();
System.out.println("---------------------------------");
System.out.println("cglib动态代理---有比赛,联系运动员代理");
//IRunner cglibr = (IRunner) new CglibRunnerAgent().createProxyObject(new Runner());
Runner cglibr = (Runner) new CglibRunnerAgent().createProxyObject(new Runner());
cglibr.run();
}
}
效果:
动态代理指的是在运行时在生成的代理类。
jdk动态代理和cglib的不同是:
jdk动态代理,需要被代理的类有接口;
cglib可以直接代理一个类,无需其有接口,原理是对一个类生成一个子类。所以被final修饰的类,不能继承因而不能用cglib动态代理。