AOP基础

【Why AOP ?】

1.代码混乱:越来越多的非业务需求(日志和验证等)加入后,原有的业务方法急剧膨胀。每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点。

2.代码分散:以日志需求为例,知识为了满足这个单一需求,就不得不在多个模块(方法)里多次重复相同的日志代码。如果日志需求发生变化,必须修改所有模块。

示例:

ArithmeticCalculator.java:

1 package com.hk.spring.aop.helloworld;
2 
3 public interface ArithmeticCalculator {
4     int add(int i,int j);
5     int sub(int i,int j);
6     int mul(int i,int j);
7     int div(int i,int j);
8 }

ArithmeticCalculatorImpl.java:

 1 package com.hk.spring.aop.helloworld;
 2 
 3 public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
 4 
 5     @Override
 6     public int add(int i, int j) {
 7         System.out.println("The method add begins with["+ i + "," + j +"]");
 8         int result = i + j;
 9         System.out.println("The mathod add ends with " + result);
10         return result;
11     }
12 
13     @Override
14     public int sub(int i, int j) {
15         System.out.println("The method sub begins with["+ i + "," + j +"]");
16         int result = i - j;
17         System.out.println("The mathod sub ends with " + result);
18         return result;
19     }
20 
21     @Override
22     public int mul(int i, int j) {
23         System.out.println("The method mul begins with["+ i + "," + j +"]");
24         int result = i * j;
25         System.out.println("The mathod mul ends with " + result);
26         return result;
27     }
28 
29     @Override
30     public int div(int i, int j) {
31         System.out.println("The method div begins with["+ i + "," + j +"]");
32         int result = i / j;
33         System.out.println("The mathod div ends with " + result);
34         return result;
35     }
36 
37 }

运行结果:

【使用动态代理解决上述问题】

1.代理设计模式的原理:使用一个代理对象将对象包装起来,然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。

ArithmeticCalculatorImpl.java:

 1 package com.hk.spring.aop.helloworld;
 2 
 3 public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
 4 
 5     @Override
 6     public int add(int i, int j) {
 7         int result = i + j;
 8         return result;
 9     }
10 
11     @Override
12     public int sub(int i, int j) {
13         int result = i - j;
14         return result;
15     }
16 
17     @Override
18     public int mul(int i, int j) {
19         int result = i * j;
20         return result;
21     }
22 
23     @Override
24     public int div(int i, int j) {
25         int result = i / j;
26         return result;
27     }
28 
29 }

ArithmeticCalculatorLoggingProxy.java:

 1 package com.hk.spring.aop.helloworld;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 import java.lang.reflect.Proxy;
 6 import java.util.Arrays;
 7 
 8 public class ArithmeticCalculatorLoggingProxy {
 9     //要代理的对象
10     private ArithmeticCalculator target;
11 
12     public ArithmeticCalculatorLoggingProxy(ArithmeticCalculator target) {
13         this.target = target;
14     }
15     
16     public ArithmeticCalculator getLoggingProxy(){
17         ArithmeticCalculator proxy = null;
18         //代理对象由哪一个类加载器负责加载
19         ClassLoader loader = target.getClass().getClassLoader();
20         //代理对象的类型,即其中有哪些方法
21         Class [] interfaces = new Class[]{ArithmeticCalculator.class};
22         //当调用代理对象其中的方法时,该执行的代码
23         InvocationHandler h = new InvocationHandler() {
24             /**
25              *proxy:正在返回的那个代理对象,一般情况下,在invoke方法中都不使用该对象。
26              *method:正在被调用的方法
27              *args:调用方法时,传入的参数
28              */
29             @Override
30             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
31                 String methodName = method.getName();
32                 //日志
33                 System.out.println("The method " + methodName + "begins with " + Arrays.asList(args));
34                 //执行方法
35                 Object result = method.invoke(target, args);
36                 //日志
37                 System.out.println("The method " + methodName + "ends with " + result);
38                 return result;
39             }
40         }; 
41         proxy = (ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h);
42         return proxy;
43     }
44 }

Main.java:

 1 package com.hk.spring.aop.helloworld;
 2 
 3 public class Main {
 4     public static void main(String[] args) {
 5 //        ArithmeticCalculator arithmeticCalculator = null;
 6 //        arithmeticCalculator = new ArithmeticCalculatorImpl();
 7         
 8         ArithmeticCalculator target = new ArithmeticCalculatorImpl();
 9         ArithmeticCalculator proxy = new ArithmeticCalculatorLoggingProxy(target).getLoggingProxy();
10         
11         int result = proxy.add(1, 2);
12         System.out.println("-->"+result);
13         
14         result = proxy.div(4, 2);
15         System.out.println("-->"+result);
16     }
17 
18 }

运行结果:

【AOP简介】

1.AOP(Aspect-Oriented Programming,面向切面编程):是一种新的方法论,是对OOP(Object-Oriented Programming,面向对象编程)的补充。

2.AOP的主要编程对象是切面(aspect),而切面模块化横切关注点

3.在应用AOP编程时,仍然需要定义公共功能,但可以明确地定义这个功能在哪里,以什么方式应用,并且不必修改受影响的类。这样一来横切关注点就被模块化到特殊的对象(切面)里。

4.AOP的好处:

--每个事物逻辑位于一个位置,代码不分散,便于维护和升级。

--业务模块更简洁,只包含核心业务代码。

每接触一个新领域,我就像一块掉进水里的海绵,四面八方的养分都让我不断充实。O(∩_∩)O~
原文地址:https://www.cnblogs.com/zhzcode/p/9652194.html