动态代理,有两种情况,第一种是有接口的情况下,你可以选择为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...
最新评论
徒弟可以A师傅,学生可以A老师,为什么外包不能A正式,我觉得很正常。异性相吸这是宇宙真理
PHP天下第一(狗头叼花)
第一个不需要关注公主号直接给激活码的帖子!
客户端超时断开后,服务端如果没有设置超时机制,那也会继续等待处理,万一这期间有消息到了,那不是就接受到消息处理了,但是也没有办法返回到客户端,导致消息丢失。
企业级GO项目开发实战 Kubernetes权威指南 第六版
https://pan.baidu.com/s/1q3bnTncIACKoTZFxvx7BQw?pwd=ii7n
RabbitMQ精讲,项目驱动落地,分布式事务拔高 有吗?
Spring Cloud Alibaba 微服务架构实战 https://pan.baidu.com/s/1jF5voFRoeF0lYAzAPBWSbw?pwd=chqk