JAVA代理详解

来源:互联网 发布:tensorflow syntaxnet 编辑:程序博客网 时间:2024/06/14 02:34

1.什么是动态代理?

答:动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实。代理一般会实现它所表示的实际对象的接口。代理可以访问实际对象,但是延迟实现实际对象的部分功能,实际对象实现系统的实际功能,代理对象对客户隐藏了实际对象。客户不知道它是与代理打交道还是与实际对象打交道。

2.为什么使用动态代理?

答:因为动态代理可以对请求进行任何处理

3.使用它有哪些好处?

答:因为动态代理可以对请求进行任何处理

4.哪些地方需要动态代理?

答:不允许直接访问某些类;对访问要做特殊处理等

目前Java开发包中包含了对动态代理的支持,但是其实现只支持对接口的的实现。 其实现主要通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。 

Proxy类主要用来获取动态代理对象,InvocationHandler接口用来约束调用者实现

以下为模拟案例,通过动态代理实现在方法调用前后向控制台输出两句字符串

目录结构:


实例代码:

5、接口

package com.ren.day03;import java.lang.reflect.Method;//代理类接口public interface Advice {void beforeMehtod(Method method);void afterMehtod(Method method);}

6、实现了该接口的类

package com.ren.day03;import java.lang.reflect.Method;public class MyAdvice implements Advice {private long start = 0;private long end = 0;@Overridepublic void beforeMehtod(Method method) {// TODO Auto-generated method stubSystem.out.println("方法调用前");start = System.currentTimeMillis();}@Overridepublic void afterMehtod(Method method) {// TODO Auto-generated method stubend = System.currentTimeMillis();System.out.println(method.getName() + "run time :" + (end - start));System.out.println("方法调用后");}}

7、测试类

package com.ren.day03;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationHandler;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.ArrayList;import java.util.Collection;public class ProxyTest {/** * @param args * @throws NoSuchMethodException  * @throws SecurityException  * @throws InvocationTargetException  * @throws IllegalAccessException  * @throws InstantiationException  * @throws IllegalArgumentException  */public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {// TODO Auto-generated method stubClass clazzProxy = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);System.out.println(clazzProxy.getName());System.out.println("---------Begin constructor list---------");Constructor[] constructors = clazzProxy.getConstructors();for (Constructor constructor : constructors) {String name = constructor.getName();StringBuilder sb = new StringBuilder(name);sb.append("(");Class[] clazzParaType = constructor.getParameterTypes();for (Class clazzPara : clazzParaType) {sb.append(clazzPara.getName());sb.append(",");}if (clazzParaType.length != 0)sb.deleteCharAt(sb.length() - 1);sb.append(")");System.out.println(sb.toString());}System.out.println("---------Begin method list---------");Method[] methods = clazzProxy.getMethods();for (Method method : methods) {String name = method.getName();StringBuilder sb = new StringBuilder(name);sb.append("(");Class[] clazzParaType = method.getParameterTypes();for (Class clazzPara : clazzParaType) {sb.append(clazzPara.getName());sb.append(",");}if (clazzParaType.length != 0)sb.deleteCharAt(sb.length() - 1);sb.append(")");System.out.println(sb.toString());}System.out.println("-----------Create instance object--------------");//clazzProxy.newInstance();//得到构造器Constructor constructor = clazzProxy.getConstructor(InvocationHandler.class);//实现InvocationHandler接口class MyInvocationHandler implements InvocationHandler {@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// TODO Auto-generated method stubreturn null;}}//创建实例对象1Collection proxy1 = (Collection)constructor.newInstance(new MyInvocationHandler());//调用方法System.out.println(proxy1);System.out.println(proxy1.toString());//从toString方法可以看出创建实例对象成功,至于打印为什么是null,是因为toString方法返回null//创建实例对象2,用内部类实现InvocationHandler接口Collection proxy2 = (Collection)constructor.newInstance(new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// TODO Auto-generated method stubreturn null;}});//创建实例对象3,直接用Rroxy,newProxyInstance方法/*Collection proxy3 = (Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(), new Class[]{Collection.class}, new InvocationHandler() {ArrayList target = new ArrayList(); @Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// TODO Auto-generated method stubSystem.out.println("方法调用前");long start = System.currentTimeMillis();Object obj = method.invoke(target, args);long end = System.currentTimeMillis();System.out.println(method.getName() + "run time :" + (end - start));System.out.println("方法调用后");return obj;}});*/final ArrayList target = new ArrayList(); Collection proxy3 = getProxy(target,new MyAdvice());//再次调用方法proxy3.add("fff");proxy3.add("fff");proxy3.add("fff");System.out.println(proxy3.size());}//创建实例对象3,直接用Rroxy,newProxyInstance方法public static Collection getProxy(final ArrayList target,final Advice advice) {Collection proxy3 = (Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(), new Class[]{Collection.class}, new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// TODO Auto-generated method stubadvice.beforeMehtod(method); //通过对象传入方法Object obj = method.invoke(target, args);advice.afterMehtod(method); return obj;}});return proxy3;}}



原创粉丝点击