欢迎您的访问
专注于分享最有价值的互联网技术干货

java动态代理的两种方法

几个T的资料等你来白嫖
双倍快乐

动态代理,有两种情况,第一种是有接口的情况下,你可以选择为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... 
赞(0) 打赏
版权归原创作者所有,任何形式转载请联系我们:大白菜博客 » java动态代理的两种方法

评论 抢沙发

0 + 8 =
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏