您的位置:首页 > 编程语言 > Java开发

java动态代理的两种方法

2017-02-13 16:09 218 查看
动态代理,有两种情况,第一种是有接口的情况下,你可以选择为jdk自带的动态代理的方式来编写程序,但你想要为一个实在的类编写动态代理的方式的话,这时候就必须选择一些开源的lib包,如cglib包,同时还需要asm包。
cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制。

第一种通过jdk的动态代理(必须接口):
主类(实现主要方法的类)接口:

Java代码


package bean;

public interface TestInter {

public void save();

}

具体类:

package bean;

public class TestClass implements TestInter{

public void save(){

System.out.println("调用TestClass.save()");

}

}

代理类:

Java代码


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;

}

}

测试类:

Java代码


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();

}

}

}

运行结果:

Java代码


coming here...

start...

调用TestClass.save()

end...

第二种方法:

主类(实现主要方法的类):

Java代码


package cglib;

public class TestClass {

public void save(){

System.out.println("调用TestClass.save()");

}

}

拦截器类(实现功能的地方):

Java代码


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;

}

}

创建代理的类:

Java代码


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();

}

}

测试类

Java代码


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();

}

}

运行结果:

Java代码


start...

调用TestClass.save()

ending...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: