• 三(一)、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配置中

    我从来不相信什么懒洋洋的自由。我向往的自由是通过勤奋和努力实现的更广阔的人生。 我要做一个自由又自律的人,靠势必实现的决心认真地活着。
  • 相关阅读:
    Redis学习笔记(三):Redis常见命令
    Redis学习笔记(一):Redis安装与配置
    Redis学习笔记(二):Redis介绍
    微服务 第八章 SpringBoot多数据源的配置(通过Spring Data JPA 的方式)
    微服务 第七章 SpringBoot多数据源的配置(通过JdbcTemplate的方式)
    微服务 第六章 springboot 通过Spring-data-jpa 配置Oracle数据源(Spring-data-jpa详细介绍)
    微服务 第六章 springboot 通过Spring-data-jpa 配置Oracle数据源(简单步骤)
    java通过jdbc对数据库进行增删改查(摘录)
    ---awk 调shell 命令的方法
    ---Linux 10 年的硕果累累啊!
  • 原文地址:https://www.cnblogs.com/lixiuming521125/p/15415468.html
Copyright © 2020-2023  润新知