zoukankan      html  css  js  c++  java
  • Spring4.0学习笔记(10) —— Spring AOP

    个人理解:

        Spring AOP 与Struts 的 Interceptor 拦截器 有着一样的实现原理,即通过动态代理的方式,将目标对象与执行对象结合起来,降低代码之间的耦合度,主要运用了Proxy这个静态类,通过newProxyInstance方法将目标对象与插入对象进行结合,java中推崇面向接口编程,因此,首先创建一个接口类,定义待实现的方法

    package com.spring.aop;
    
    public interface ICaculate {
    
        int add(int i,int j);
        int sub(int i,int j);
        int mul(int i,int j);
        int div(int i,int j);
    }

    接着,定义实现类,实现接口中的方法

    package com.spring.aop;
    
    public class Caculate implements ICaculate{
    
        public int add(int i, int j) {
            int result = i + j;
            return result;
        }
    
        public int div(int i, int j) {
            int result = i / j;
            return result;
        }
    
        public int mul(int i, int j) {
            int result = i * j;
            return result;
        }
    
        public int sub(int i, int j) {
            int result = i - j;
            return result;
        }
    }

    最核心的部分,建立工厂类,使用动态代理,需要实现InvocationHandler接口,在这里,定义为内部类,直接在内部类中实现Invoke方法

    package com.spring.aop;
    
    import java.lang.reflect.*;
    import java.util.Arrays;
    
    
    /**
     * 切面:如验证、前置日志、后置日志
     * 通知:切面必须完成的工作
     * 目标:被通知的对象,此例为业务逻辑
     * 代理:向目标对象应用通知之后创建的对象
     * @author 凯
     *
     */
    public class CaculateLoggingProxy {
        
        //代理的对象
        private ICaculate target;
        
        public CaculateLoggingProxy(ICaculate target) {
            this.target = target;
        }
        
        @SuppressWarnings({"unchecked" })
        /**
         * 接口也可以定义为返回类型
         */
        public ICaculate getLoggingProxy(){
            ICaculate proxy = null;
            //代理对象由哪一个类加载器加载
            ClassLoader loader = target.getClass().getClassLoader();
            //代理对象的类型,其中有哪些方法
            Class [] interfaces = new Class[]{ICaculate.class};
            
            InvocationHandler h = new InvocationHandler() {
                /**
                 * proxy: 正在返回的那个代理对象,一般情况下,在invoke 方法中都不使用该对象
                 * method: 正在被调用的方法
                 * args: 调用方法时传入的参数
                 */
                public Object invoke(Object proxy, Method method, Object[] args)
                        throws Throwable {
                    //方法名
                    String methodName = method.getName();
                    System.out.println("begin with = ["+methodName+"] params = ["+Arrays.asList(args)+"]");
                    //执行方法
                    Object result = method.invoke(target, args);
                    System.out.println("end with = ["+methodName+"] result = ["+result+"]");
                    return result;
                }
            };
            proxy = (ICaculate)Proxy.newProxyInstance(loader, interfaces, h);
            return proxy;
        }
    }

    写一个测试类,测试是否成功

    package com.spring.aop;
    
    public class Main {
        public static void main(String[] args) {
            ICaculate target = new Caculate();
            ICaculate proxy = new CaculateLoggingProxy(target).getLoggingProxy();
            
            int a = proxy.add(1, 1);
            System.out.println(a);
            
            int b = proxy.add(1, 2);
            System.out.println(b);
            
        }
    }

    输出结果:

    begin with = [add] params = [[1, 1]]
    end with = [add] result = [2]
    2
    begin with = [add] params = [[1, 2]]
    end with = [add] result = [3]
    3

  • 相关阅读:
    C++ <cstring> 里的一些常用函数
    Hadoop_第一次作业
    线性回归理解和应用例子
    条款28 :避免返回handles指向对象内部成分
    条款25 :尽可能延后变量定义式的出现时间
    条款21 :必须返回对象时,别妄想返回其reference
    条款16:成对使用new和delete时要采用相同的形式
    条款22 :将成员变量声明为private
    条款13:以对象管理资源
    条款12:复制对象时勿忘其每一个成分
  • 原文地址:https://www.cnblogs.com/cklovefan/p/5308498.html
Copyright © 2011-2022 走看看