如果你去面试Java开发, 那么spring的AOP和DI几乎是必问的问题。
那么AOP是什么呢?
一. AOP所谓Aop就是 Aspect-OrientedProgramming, 中文就是面向切面编程。
我们之前听说面向过程编程, 以及面向对象编程, 而这个面向切面编程我们可以视为是面向对象编程的1个补充(增强);
在一般的方法(函数)中, 为了方便,可能只写了业务代码
1. 业务代码
而我们我们可以将其补充成4个部分。
验证参数
前置日志
业务代码
后置日志
1.1 横切关注点 (Crosscutting Concerns)大家看上面的方法, 就像用刀子把1个方法横向切成4块, 我们把上面除业务代码外任意一个部分就叫做横切关注点.
1.2 切面 (Aspect)我们可以把横切关注点进行分组, 其中任意一组就叫做切面
例如上面的例子中, 我们可以分成
验证切面 (1. 验证参数)
日志切面 (2. 前置日志, 4.后置日志)
1.3 通知 (Advice)所谓通知就是切面要完成的工作。
例如对于日志通知来讲, 里面执行日志的方法我们就可以称为1个通知。
1.4 目标 (Target)所谓目标就是被通知的对象, 也就是指上面例子中的原方法本身啦。
1.5 代理 (Proxy)当目标被通知后产生的对象就叫做代理, 因为AOP的原理就是利用代理来实现的, 如果想了解动态代理的可以参考这里
1.6 连接点 (Joinpoint)所谓Joinpoint就是程序执行到的某个位置,
上面例子中, 业务代码方法的执行之前, 执行之后, 抛出异常后 都可以视为某个连接点。
1.7 切点 (PointCut)每个方法都存在多个连接点, 而Spring AOP利用切点来定位到具体那些连接点。
Joinpoint 和 PointCut 的关系可以作如下比喻,假如Joinpoint的数据里的记录, 那么PointCut就相当于查询条件
而Spring的AOP 能在不修改具体某个方法的前提下, 利用动态代理技术将通知注入到这个方法的各个连接点中, 令到这个方法得到了必要的补充。
对于上面的例子种, 我们原来的方法只有业务代码, 但是我们可以利用Spring AOP加入 验证参数, 日志等功能!
二. 具体例子 2.1 还没使用AOP的例子我们首先利用spring创建两个计算类。
1个加法类, 1个减法类。
bean config xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <!-- auto scan --> <context:component-scan base-package="com.home.aop"></context:component-scan> </beans>注意引入aop命名空间
计算接口 Calculator
package com.home.aop; public interface Calculator { public double getResult(double a, double b); }加法类 AddCalculator
package com.home.aop; import org.springframework.stereotype.Component; @Component public class AddCalculator implements Calculator { @Override public double getResult(double a, double b) { return a + b; } }减法类 SubCalculator
package com.home.aop; import org.springframework.stereotype.Component; @Component public class SubCalculator implements Calculator { @Override public double getResult(double a, double b) { return a - b; } }Client 代码
package com.home.aop; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AopMain { public static void f(){ g(); } public static void g(){ ApplicationContext ctx = new ClassPathXmlApplicationContext("bean-aop.xml"); Calculator addCal = (Calculator) ctx.getBean("addCalculator"); Calculator subCal = (Calculator) ctx.getBean("subCalculator"); System.out.println(addCal.getResult(3, 1)); System.out.println(subCal.getResult(3, 1)); } }