zoukankan      html  css  js  c++  java
  • 三(一)、aop面向切面编程由来

    概述:

    其实就是AOP作用就是:把分散在各个地方的功能分离出来形成组件。这样理解起来非常抽象;

    实例说明:

    看如下代码,ArithmeticCaculatorImpl 实现了ArithmeticCaculator,也就是一个实现计算加、减、乘、除的一个功能;此时如果想在每个方法得到结果之前,插入日志,表示方法开启,计算完成之后,添加日志表示计算完成该如何实现。可以在每个方法的计算语句前后加上打印日志;

     1 public interface ArithmeticCaculator {
     2     
     3     int add(int i,int j);
     4     int sub(int i,int j);
     5     
     6     int mul(int i,int j);
     7     int div(int i,int j);
     8     
     9 
    10 }
     1 public class ArithmeticCaculatorImpl implements ArithmeticCaculator {
     2 
     3     @Override
     4     public int add(int i, int j) {
     5         int result = i+j;
     6         return result;
     7     }
     8 
     9     @Override
    10     public int sub(int i, int j) {
    11         int result = i-j;
    12         return result;
    13     }
    14 
    15     @Override
    16     public int mul(int i, int j) {
    17         int result = i*j;
    18         return result;
    19     }
    20 
    21     @Override
    22     public int div(int i, int j) {
    23         int result = i/j;
    24         return result;
    25     }
    26 
    27 }

    方案一手动日志

    可以在每个方法的计算语句前后加上打印日志的解决方式。代码如下;

     1 public class ArithmeticCaculatorImpl implements ArithmeticCaculator {
     2 
     3     @Override
     4     public int add(int i, int j) {
     5         System.out.println("the method add begins with["+i+"+"+j+"]");
     6         int result = i+j;
     7         System.out.println("the method add begins with "+result);
     8         return result;
     9     }
    10 
    11     @Override
    12     public int sub(int i, int j) {
    13         System.out.println("the method add begins with["+i+"-"+j+"]");
    14         int result = i-j;
    15         System.out.println("the method add begins with "+result);
    16         return result;
    17     }
    18 
    19     @Override
    20     public int mul(int i, int j) {
    21         System.out.println("the method add begins with["+i+"*"+j+"]");
    22         int result = i*j;
    23         System.out.println("the method add begins with "+result);
    24         return result;
    25     }
    26 
    27     @Override
    28     public int div(int i, int j) {
    29         System.out.println("the method add begins with["+i+"/"+j+"]");
    30         int result = i/j;
    31         System.out.println("the method add begins with "+result);
    32         return result;
    33     }
    34 
    35 }
    View Code

    这种解决方式,维护起来非常麻烦;每添加一个计算方法(比如添加一个取模方法,就得加上对应的日志);还有一种办法就是,采用动态代理

    方案二动态代理:

    1.添加代理工厂:

     1 package lixiuming.spring.aop.helloworld;
     2 
     3 import java.lang.reflect.Proxy;
     4 
     5 public class ProxyFactory {
     6 
     7     // 调用此方法,返回一个代理类的对象,解决了问题一
     8     public static Object getProxyInstance(Object obj) {// obj为被代理类的对象
     9         ProxyHandler proxyHandler = new ProxyHandler();
    10         proxyHandler.bind(obj);;
    11         return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), proxyHandler);
    12     }
    13 }

    2.绑定代理类

     1 package lixiuming.spring.aop.helloworld;
     2 
     3 import java.lang.reflect.InvocationHandler;
     4 import java.lang.reflect.Method;
     5 import java.util.Arrays;
     6 
     7 public class ProxyHandler implements InvocationHandler {
     8 
     9     private Object obj;
    10 
    11     public void bind(Object obj) {
    12         this.obj = obj;
    13     }
    14 
    15     @Override
    16     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    17         // TODO Auto-generated method stub
    18 
    19         String methodName = method.getName();
    20         System.out.println("the method " + methodName + "begins with" + Arrays.asList(args));
    21         Object result = method.invoke(obj, args);
    22         System.out.println("the method " + methodName + "begins with" + result);
    23         return method.invoke(obj, args);
    24     }
    25 
    26 }

    测试:

     1     public static void main(String[] args) {
     2 
     3         ArithmeticCaculator arithmeticCaculator1 = (ArithmeticCaculator) ProxyFactory
     4                 .getProxyInstance(new ArithmeticCaculatorImpl());
     5         int result11 = arithmeticCaculator1.add(1, 2);
     6         System.out.println("-->" + result11);
     7 
     8         int result22 = arithmeticCaculator1.div(4, 2);
     9         System.out.println("-->" + result22);
    10 
    11         int result33 = arithmeticCaculator1.mul(4, 2);
    12         System.out.println("-->" + result33);
    13 
    14         int result44 = arithmeticCaculator1.sub(4, 2);
    15         System.out.println("-->" + result44);
    16 
    17     }

    运行结果:

    the method addbegins with[1, 2]

    the method addbegins with3

    -->3

    the method divbegins with[4, 2]

    the method divbegins with2

    -->2

    the method mulbegins with[4, 2]

    the method mulbegins with8

    -->8

    the method subbegins with[4, 2]

    the method subbegins with2

    -->2

     这个运行结果和 在每个方法的计算语句前后加上打印日志的解决方式 结果一样;但是配置还是不是那么灵活(比如想配置某个包下面的所有方法,都需要执行日志,那么每次调用该方法的动态代理等问题没有很好的解决)。spring提供了aop方式的解决方案;

    方案三spring aop

    实现代码放在下一篇三(二)、AOP配置中

    我从来不相信什么懒洋洋的自由。我向往的自由是通过勤奋和努力实现的更广阔的人生。 我要做一个自由又自律的人,靠势必实现的决心认真地活着。
  • 相关阅读:
    洛谷 1339 最短路
    洛谷 1330 封锁阳光大学 图论 二分图染色
    洛谷 1262 间谍网络 Tarjan 图论
    洛谷 1373 dp 小a和uim之大逃离 良心题解
    洛谷 1972 莫队
    洛谷 2158 数论 打表 欧拉函数
    洛谷 1414 数论 分解因数 水题
    蒟蒻的省选复习(不如说是noip普及组复习)————连载中
    关于筛法
    关于整数划分的几类问题
  • 原文地址:https://www.cnblogs.com/lixiuming521125/p/15415468.html
Copyright © 2011-2022 走看看