zoukankan      html  css  js  c++  java
  • Java——动态代理


             

              在静态代理中,我们在调用target类的时候,都是先拿到proxy类。由于proxy类中将target类作为了成员变量,而且跟target类继承了一样的接口,具有同样的方法,所以,在proxy类中。通过调用target类的方法来对目标类方法的运行前后插入特殊操作。


             可是静态代理有俩缺点:1,代理类特别多,每添加一个target类。就要写一个代理。2,在proxy类中,可能我们须要插入的操作时同样的。这就造成了代码的反复。


                 所以。通过引入反射,能够实现动态代理,以对静态代理进行改进。



    /**
     * @ClassName: LogHandler
     * @Description: 用于创建代理类
     * @author 水田
     * @date 2015年12月8日 上午11:17:51
     */
    public class LogHandler implements InvocationHandler {
        private Object targetObject;
    
        public Object newProxyInstance(Object targetObj) {
    	this.targetObject = targetObj;
    	/*
    	 * 1,拿到类的classLoader
    	 * 2,得到创建的类的接口
    	 * 3,传入回调invoke方法所在类
    	 * */
    	return Proxy.newProxyInstance(targetObj.getClass().getClassLoader(),
    		targetObj.getClass().getInterfaces(), this);
        }
    
        /*
         * (非 Javadoc) <p>Title: invoke</p> <p>Description: </p>
         * 
         * @param proxy
         * 
         * @param 调用方法信息
         * 
         * @param args:方法的參数数组
         * 
         * @return
         * 
         * @throws Throwable
         * 
         * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
         * java.lang.reflect.Method, java.lang.Object[])
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
    	    throws Throwable {
    	for (int i = 0; i < args.length; i++) {
    	    System.out.println(args[i]);
    	}
    	try {
    	    // 调用目标类的方法,返回一个object,假设方法没有返回值,则返回null
    	    method.invoke(targetObject, args);
    	} catch (Exception e) {
    	    e.printStackTrace();
    	    throw e;
    	}
    
    	System.out.println("start----->>>" + method.getName());
    	return method.getName();
        }
    }
    

           使用演示样例:


    /* 动态代理演示样例 */
    	LogHandler logHandler = new LogHandler();
    	UserManager userManager = (UserManager) logHandler
    		.newProxyInstance(new UserManagerImpl());
    	userManager.addUser("2343254", "lhc");
    


           我们将target类中被调用方法运行前后要插入的操作放在回调函数invoke方法中,当使用代理类调用相应方法的时候。会直接进入invoke方法这里。使用method,和invoke第三个參数能够拿到被调用方法的信息。


            添加了动态代理之后。明显去掉了静态代理的两个小缺点。大笑





  • 相关阅读:
    linux下的apue.3e安装[Unix环境高级编程]
    mysql将主键序号置为1
    玛丽全开-许愿池
    redis学习之路

    jvm
    oracle版本号含义
    oracle查看所有的表空间
    oracle存储过程 package
    oracle同义词创建(synonym)
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/6914299.html
Copyright © 2011-2022 走看看