动态代理,有两种情况,第一种是有接口的情况下,你可以选择为jdk自带的动态代理的方式来编写程序,但你想要为一个实在的类编写动态代理的方式的话,这时候就必须选择一些开源的lib包,如cglib包,同时还需要asm包。
cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制。
第一种通过jdk的动态代理(必须接口):
主类(实现主要方法的类)接口:
package bean;
public interface TestInter {
public void save();
}
具体类:
package bean;
public class TestClass implements TestInter{
public void save(){
System.out.println("调用TestClass.save()");
}
}
代理类:
package bean;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.apache.log4j.Logger;
public class Test implements InvocationHandler {
private Object originalObject;
public Object bind(Object obj) {
System.out.println("coming here...");
this.originalObject = obj;
return Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),this
);
}
/**
* 反射?
*/
public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
Object result=null;
if(arg1.getName().startsWith("save")){
System.out.println("start...");
result=arg1.invoke(this.originalObject,arg2);
System.out.println("end...");
}
return result;
}
}
测试类:
package bean;
public class TestMain {
/**
* @param args
*/
public static void main(String[] args) {
Test test=new Test();
TestClass tc=new TestClass();
try{
((TestInter)test.bind(tc)).save();
}catch(Exception e){
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
运行结果:
coming here...
start...
调用TestClass.save()
end...
第二种方法:
主类(实现主要方法的类):
package cglib;
public class TestClass {
public void save(){
System.out.println("调用TestClass.save()");
}
}
拦截器类(实现功能的地方):
package cglib;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
* 实现接口MethodInterceptor
*/
public class MyMethodInterceptor implements MethodInterceptor {
/**
* 拦截器,在这里实现需要的功能
* 在这里仅仅是在执行之前打印了start 在执行之后打印了end
*/
public Object intercept(Object arg0, Method arg1, Object[] arg2,
MethodProxy arg3) throws Throwable {
System.out.println("start...");
Object result = arg3.invokeSuper(arg0,arg2);
System.out.println("ending...");
return result;
}
}
创建代理的类:
package cglib;
import net.sf.cglib.proxy.Enhancer;
public class TestProxy {
/**
* 创建代理类
* @param targetClass
* @return
*/
public Object createProxy(Class targetClass){
Enhancer enhancer = new Enhancer();
//设定父类???
enhancer.setSuperclass(targetClass);
//这里貌似是进行回调,主要的操作被放进了MyMethodInterceptor类里
enhancer.setCallback(new MyMethodInterceptor());
return enhancer.create();
}
}
测试类
package cglib;
public class TestMain {
/**
* 测试类
* @param args
*/
public static void main(String[] args) {
TestClass tc=new TestClass();
TestProxy tp=new TestProxy();
TestClass tcp=(TestClass)tp.createProxy(tc.getClass());
tcp.save();
}
}
运行结果:
start...
调用TestClass.save()
ending...
最新评论
命令: nload
真是个良心站点哇,大公无私,爱了爱了
还可以直接搞一张映射表,存 uid | time | source_index, 第一次直接查对应的 time 选出前100, 第二次直接用 CompleteFuture 去分别用 source_in
干得漂亮,多个朋友堵条路
2021.2.2版本的不适用吧
现在还可以用么
激活码有用,感谢分享
激活码的地址打不开了