黑马程序员:动态代理

来源:互联网 发布:主力资金净流入额 知乎 编辑:程序博客网 时间:2024/05/17 02:15

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

AOP:面向方面的编程——目标是要将交叉业务模块化

    安全、事务、日志等功能要贯穿到好多个模块中,这就是交叉业务


动态代理技术

   JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。

import java.lang.reflect.Constructor;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.ArrayList;import java.util.Collection;public class ProxyTest {public static void main(String[] args) throws Exception{// TODO Auto-generated method stubClass clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);System.out.println(clazzProxy1.getName());Constructor[] constructors = clazzProxy1.getConstructors();for(Constructor constructor : constructors){String name = constructor.getName();StringBuilder sBuilder = new StringBuilder(name);sBuilder.append('(');Class[] clazzParams = constructor.getParameterTypes();for(Class clazzParam : clazzParams){sBuilder.append(clazzParam.getName()).append(',');}if(clazzParams!=null && clazzParams.length != 0)sBuilder.deleteCharAt(sBuilder.length()-1);sBuilder.append(')');System.out.println(sBuilder.toString());}Method[] methods = clazzProxy1.getMethods();for(Method method : methods){String name = method.getName();StringBuilder sBuilder = new StringBuilder(name);sBuilder.append('(');Class[] clazzParams = method.getParameterTypes();for(Class clazzParam : clazzParams){sBuilder.append(clazzParam.getName()).append(',');}if(clazzParams!=null && clazzParams.length != 0)sBuilder.deleteCharAt(sBuilder.length()-1);sBuilder.append(')');System.out.println(sBuilder.toString());}Constructor constructor = clazzProxy1.getConstructor(InvocationHandler.class);class MyInvocationHander1 implements InvocationHandler{public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// TODO Auto-generated method stubreturn null;}}Collection proxy1 = (Collection)constructor.newInstance(new MyInvocationHander1());System.out.println(proxy1);proxy1.clear();Collection proxy2 = (Collection)constructor.newInstance(new InvocationHandler(){public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {return null;}});final ArrayList target = new ArrayList();Collection proxy3 = (Collection)getProxy(target,new MyAdvice());proxy3.add("zxx");proxy3.add("lhm");proxy3.add("bxd");System.out.println(proxy3.size());System.out.println(proxy3.getClass().getName());}private static Object getProxy(final Object target,final Advice advice) {Object proxy3 = Proxy.newProxyInstance(target.getClass().getClassLoader(),new InvocationHandler(){public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {/*long beginTime = System.currentTimeMillis();Object retVal = method.invoke(target, args);long endTime = System.currentTimeMillis();System.out.println(method.getName() + " running time of " + (endTime - beginTime));return retVal;*/advice.beforeMethod(method);Object retVal = method.invoke(target, args);advice.afterMethod(method);return retVal;}});return proxy3;}}


加系统功能的位置:

1、在调用目标方法之前

2、在调用目标方法之后

3、在调用目标方法前后

4、在处理目标方法异常的catch块中


动态代理的三种创建方式

1、Proxy.getProxyClass(类加载,接口)获取字节码文件,再根据字节码获取构造函数,Proxy只有一个带参的构造函数参数位。InvocationHandler的对象,通过反射获取,在new InvocationHandler获取对象

2、使用匿名内部类:new InvocationHandler(){}

3、Proxy.newProxyInstance方法


0 0
原创粉丝点击