代理


动态代理技术可以动态的生成一段内部有一个被扩展类引用的代码,生成的类类似于用组合这种方式,并把它动态的编译成class文件,然后装载进jvm中执行。著名的框架Spring的核心技术之一aop就是使用的就是动态代理技术。

 Java中为动态代理提供了支持,用到了类Proxy用于产生代理,还有一个接口InvocationHandler,用于在被代理的类的方法前后加入处理逻辑,这个接口内部有一个invoke方法,invoke接受三个参数,

代理Proxy 基本概念

安全、事物、日志要贯穿到好多模块中,就是交叉业务

AOP面向方面编程

目标:要使交叉业务模块化,将切面代码移动到原始方法的周围
代理是实现AOP功能的核心和关键技术

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

1JVM生成的动态类必须实现一个或多个接口,JVM生成的动态类只能用作具有相同接口的目标类的代


    2
CGLIB库可以动态生成一个类的子类一个类的子类也可以用作该类的代理。,如果要为一个没有实现

接口的类生成动态代理类,那么可以使用CGLIB
   
代理方法在系统代码位置
    1
)在调用模板方法之前
    2
)在调用模板方法之后
    3
)在调用模板方法之前后
    4
)在处理目标方法异常的catch块中

二、创建代理
InvocationHandler
接口
   
创建实现Collection接口的动态类和查看其名称,分析Proxy.getProxyClass方法的各个参数

    创建动态类的实例对象
       1
)用反射获得构造方法
       2
)编写一个简单的InvocationHandler
       3
)调用构造方法创建动态类的实例对象,并编写的InvocationHandler类的实例对象穿进去
   InvocationHandler
的运行原理
创建某一接口 MyInterface的代理:
     InvocationHandler handler = newMyInvocationHandler(...);
           
代理实例调用处理程序实现的接口,对代理实例调用方法时,将对方法调用进行编码并将其指

派到它的调用处理程序的 invoke方法
Class proxyClass = Proxy.getProxyClass(MyInterface.class.getClassLoader(), new Class[] { MyInterface .class });
得到接口代理类的类加载器,要接口数组(因为可能要加载的不是一个接口)
MyInterface myint = (MyInterface ) proxyClass.getConstructor(newClass[]{               

 InvocationHandler.class}).newInstance(new Object[] { handler });

创建代理的示例代码:

package lianxi;

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 {

	/**
	 * @param args
	 * @throws Exception
	 * @throws SecurityException
	 */
	public static void main(String[] args) throws SecurityException, Exception {
		// TODO Auto-generated method stub

		Class clazz = Proxy.getProxyClass(Collection.class.getClassLoader(),
				Collection.class);
		Constructor[] Constructors = clazz.getConstructors();
		for (Constructor constructor : Constructors) {
			StringBuilder sb = new StringBuilder();
			sb.append("(");
			Class[] paramclazzs = constructor.getParameterTypes();
			for (Class paramclazz : paramclazzs) {
				sb.append(paramclazz.getName());
				sb.append(",");
			}
			if (paramclazzs.length != 0)
				sb.deleteCharAt(sb.length() - 1);
			sb.append(")");
			System.out.println(constructor.getName() + sb.toString());
		}
		class myInvocationHandler implements InvocationHandler {

			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				// TODO Auto-generated method stub
				return null;
			}

		}

		final ArrayList Target = new ArrayList();
		Collection coll1 = (Collection) getProxy(Target);
		coll1.add("123");
		coll1.add("456");
		coll1.add("ert");
		// System.out.println(coll1);
		System.out.println(Target);

		/*
		 * System.out.println("*************************************"); Method[]
		 * methods=clazz.getMethods(); for(Method method:methods){ StringBuilder
		 * sb=new StringBuilder(); sb.append("("); Class[]
		 * paramclazzs=method.getParameterTypes(); for(Class
		 * paramclazz:paramclazzs){ sb.append(paramclazz.getName());
		 * sb.append(","); } if(paramclazzs.length!=0)
		 * sb.deleteCharAt(sb.length()-1); sb.append(")");
		 * System.out.println(method.getName()+sb.toString()); }
		 */
	}

	private static Object getProxy(final Object Target) {
		Object coll1 = Proxy.newProxyInstance(Target.getClass()
				.getClassLoader(), Target.getClass().getInterfaces(),
				new InvocationHandler() {

					@Override
					public Object invoke(Object proxy, Method method,
							Object[] args) throws Throwable {

						// TODO Auto-generated method stub
						long starttime = System.currentTimeMillis();
						if ("123".equals(args[0]))
							args[0] = "hello";
						Object obj = method.invoke(Target, args);
						System.out.println("args:::" + args);
						// System.out.println("proxy:::"+proxy);
						long endtime = System.currentTimeMillis();
						System.out.println(method + "....runtime..."
								+ (endtime - starttime));
						return obj;
					}
				});
		return coll1;
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值