java动态代理的两种方法

本文详细介绍了Java中动态代理的两种实现方式:基于JDK自带的接口代理及使用CGLIB库进行类代理的方法。通过示例代码演示了如何创建代理对象并执行方法拦截。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

动态代理,有两种情况,第一种是有接口的情况下,你可以选择为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...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值