1,客户端 请求 代理(proxy),这时,把Invocationhandler 以参数的形式 传递给 代理(proxy)
2,客户端 在调用 代理(proxy)的其他方法,其他方法,也调用 (InvocationHandler)。
3,而 InvocationHandler 就执行,invoke方法,而这时 invoke 就可以调用目标程序,来完成 业务逻辑实现。
4,在 invocationHandler里面 有个 log方法,这里是作为一个对象,在这个对象里面 有实现的方法,来完成一些业务,正好是 spring的面向切面编程。
- package com.itm.itcast;
- 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 {
- Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
- System.out.println(clazzProxy1.getName());
- System.out.println(" 以下 :创建动态类的实例对象及调用其方法 ");
- Constructor constructor = clazzProxy1.getConstructor(InvocationHandler.class);
- class MyInvocationHandler1 implements InvocationHandler{
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- // TODO Auto-generated method stub
- return null;
- }
- }
- Collection proxy1 = (Collection) constructor.newInstance(new MyInvocationHandler1());
- System.out.println(proxy1);
- // 下面两行代码在执行的时候 都会找 invoke的,而在invoke的方法里 返回的是 null,所以会报错。,。。
- proxy1.clear();
- proxy1.size();
- System.out.println("^^^^^^^^^^^");
- Collection proxy2 = (Collection)constructor.newInstance(new InvocationHandler(){
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- return null;
- }
- });
- Collection proxy3 = (Collection)Proxy.newProxyInstance(
- Collection.class.getClassLoader(),
- /*interfaces*/
- new Class[]{Collection.class},
- /*h*/
- new InvocationHandler(){
- // 若放到这里:size() 就会打印 三。
- /*(1)*/ArrayList target = new ArrayList();
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- /*(2)*/ArrayList target = new ArrayList();
- long startTime = System.currentTimeMillis();
- Object retVal = method.invoke(target, args);
- long endTime = System.currentTimeMillis();
- System.out.println(method.getName() + " :runing time of " + (endTime - startTime));
- return retVal;
- }
- }
- );
- // 每调用 一次 add方法 就会 找一次:InvocationHandler() 的 invoke 的方法。
- proxy3.add("zxx");
- proxy3.add("lhm");
- proxy3.add("kkkk");
- System.out.println(proxy3.size());
- }
- }
以下方式 利用 动态代理:
- package com.itm.proxy;
- 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
- */
- public static void main(String[] args) throws Exception{
- final ArrayList target = new ArrayList();
- Collection proxy3 = (Collection)getProxy(target,new MyAdvice());
- proxy3.add("aaa");
- proxy3.add("bbb");
- proxy3.add("ccc");
- 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(),
- target.getClass().getInterfaces(),
- new InvocationHandler(){
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- advice.beforeMethod(method);
- Object retVal = method.invoke(target, args);
- advice.afterMethod(method);
- return retVal;
- }
- }
- );
- return proxy3;
- }
- }
接口:
- import java.lang.reflect.Method;
- public interface Advice {
- void beforeMethod(Method method);
- void afterMethod(Method method);
- }
实现接口以及相应的业务逻辑:
- import java.lang.reflect.Method;
- public class MyAdvice implements Advice {
- long beginTime = 0;
- public void afterMethod(Method method) {
- // TODO Auto-generated method stub
- System.out.println("方法后");
- long endTime = System.currentTimeMillis();
- System.out.println(method.getName() + " running time of " + (endTime - beginTime));
- }
- public void beforeMethod(Method method) {
- // TODO Auto-generated method stub
- System.out.println("方法前");
- beginTime = System.currentTimeMillis();
- }
- }
运行结果:
方法前
方法后
add running time of 0
方法前
方法后
add running time of 0
方法前
方法后
add running time of 0
方法前
方法后
size running time of 0
3
$Proxy0