1、什么是AOP呢?
AOP的全称是 Aspect-OrientedProgramming,即中文翻译里的面向切面编程。那么什么是面向切面编程,稍后来讲。先回顾一下OOP编程,即面向对象编程,这个我们很熟悉了它是按照纵向顺序来执行的,而AOP则是按照横向执行的。即它是OOP的一个补充。
(来自:https://www.cnblogs.com/zhaozihan/p/5953063.html)
2、AOP的作用
在OOP中,由于分散在各处的与对象核心功能无关的代码(横切代码),使得模块复用难度增加。AOP则将封装好放入对象剖开,找出其中对多个对象产生影响的公共行为,并将其封装成一个可重用的模块,这个模块就被命名为切面(Aspect),切面与那些业务都无关,却被封装的业务逻辑模块提取并封装起来,减少了系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。
3、面向切面编程
- 通知(增强)advice
通知定义了切面是什么以及何时使用,应该应用在某个方法被调用之前?之后?还是抛出异常时?等等。
- 连接点Join point
连接点是在应用执行过程中能够插入切面的一个点。这个点可以是调用方法时,抛出异常时,甚至修改一个字段时。切面代码可以利用这些点插入到应用的正常流程中,并添加新的行为。
- 切点(PointCut)
切点有助于缩小切面所通知的连接点的范围。如果说通知定义了切面的“什么”和“何时”的话,那么切点就定义了“何处”,切点会匹配通知所要织入的一个或多个连接点,一般常用正则表达式定义所匹配的类和方法名称来指定这些切点。
- 切面(Aspect)
切面是通知和切点的结合。通知和切点定义了切面的全部内容——它是什么,在何时何处完成其功能。
- 引入 Introduction
引入允许我们向现有的类添加新方法或属性,从而无需修改这些现有类的情况下,让他们具有新的行为和状态。
- 织入 Weaving
在过去我常常把织入与引入的概念混淆,我是这样来辨别的,“引入”我把它看做是一个定义,也就是一个名词,而“织入”我把它看做是一个动作,一个动词,也就是切面在指定的连接点被织入到目标对象中。
AOP的模型演示图:
4、简单代码演示理解
环境:windows10、JDK1.8
工具:idea
依赖包:aspectjrt.jar、aspectjweaver.jar、aspectj.jar、aopalliance.jar
1、创建方法接口
package com.xawl.spring.aop;
public interface MyAdviceInterface {
void before();
void after();
}
2、创建实现类
package com.xawl.spring.aop;
public class MyAdviceImp implements MyAdviceInterface {
@Override
public void before() {
System.out.println("this is befere advice");
}
@Override
public void after() {
System.out.println("this is after advice");
}
}
3、创建普通java类(要注入的对象)
package com.xawl.spring.aop;
public class Student {
private Integer age;
private String name;
public Integer getAge() {
System.out.println("age:"+age);
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
System.out.println("name:"+name);
return name;
}
public void setName(String name) {
this.name = name;
}
}
4、配置spring-aop.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:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
<!--配置ioc注入属性-->
<bean id="myAdviceImp" class="com.xawl.spring.aop.MyAdviceImp"></bean>
<bean id="student" class="com.xawl.spring.aop.Student">
<property name="age" value="18"></property>
<property name="name" value="空城"></property>
</bean>
<aop:config>
<!--配置aspect(切面)-->
<aop:aspect id="myAdviceImp" ref="myAdviceImp">
<!--配置pointcut(切点)-->
<aop:pointcut id="selectAll" expression="execution(* com.xawl.spring.aop.*.*(..))"></aop:pointcut>
<!--配置before(执行前记录)和after(执行后记录)-->
<aop:before method="before" pointcut-ref="selectAll"></aop:before>
<aop:after method="after" pointcut-ref="selectAll"></aop:after>
</aop:aspect>
</aop:config>
</beans>
5、创建测试类测试结果
public class MyAdviceTest {
public static void main(String[] args) {
//获取资源文件
String resources = "spring-aop.xml";
//根据资源文件创建对象
ApplicationContext context = new ClassPathXmlApplicationContext(resources);
//获取接口对象
Student student = (Student) context.getBean("student");
student.getAge();
student.getName();
}
}
6、输出测试结果
this is befere advice
age:18
this is after advice
this is befere advice
name:空城
this is after advice
7、总结说明
根据测试结果可以看出,要实现的功能都已经实现了,当然这只是一个简单的演示,实际开发中要比这个复杂许多。但是理解aop的一个原理结构已经足够了。