首先,什么是AOP呢?
AOP(Aspect Oriented Programming):面向切面编程,一种编程范式,隶属于软件工程范畴,指导开发者如何组织程序结构,AOP弥补了OOP的不足,基于OOP基础之上进行横向开发。
OOP规定程序开发以类为主体模型,一切围绕对象进行,完成某个任务先构建模型;AOP程序开发主要关注基于OOP开发中的共性功能,一切围绕共性功能进行,完成某个任务先构建可能遇到的所有共性功能(当所有功能都开发出来也就没有共性与非共性之分)
AOP的优势:
提高代码的可重用性
业务代码编码更简洁
业务代码维护更高效
业务功能拓展更便捷
1、AOP简介
AOP(Aspect-OrientedProgramming,面向切面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。
OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的复用。
而AOP技术则恰恰相反,它利用一种称为“横切”的技术。
剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。
2、AOP作用
想象下面的场景,开发中在多个模块间有某段重复的代码,我们通常是怎么处理的?显然,没有人会靠“复制粘贴”吧。在传统的面向过程编程中,我们也会将这段代码,抽象成一个方法,然后在需要的地方分别调用这个方法,这样当这段代码需要修改时,我们只需要改变这个方法就可以了。然而需求总是变化的,有一天,新增了一个需求,需要再多出做修改,我们需要再抽象出一个方法,然后再在需要的地方分别调用这个方法,又或者我们不需要这个方法了,我们还是得删除掉每一处调用该方法的地方。实际上涉及到多个地方具有相同的修改的问题我们都可以通过 AOP 来解决。
3、AOP基本使用
目录结构
主要: 接口、实现类、核心类、配置类、测试类
接口和实现类
package com.ghx.service;
public interface Bookservice {
void findAll();
void sace(int a);
int del();
void update();
}
package com.ghx.service.impl;
import com.ghx.service.Bookservice;
public class BookServiceImpl implements Bookservice {
@Override
public void findAll() {
System.out.println("查找所有");
}
@Override
public void sace(int a) {
System.out.println("保存数据");
}
@Override
public int del() {
System.out.println("删除数据");
return 0;
}
@Override
public void update() {
System.out.println("修改数据");
}
}
配置类
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--1.把所有类的对象交给IOC容器进行管理-->
<!--2.AOP的配置:让增强类 的 哪个方法 动态进行何种增强 核心类 的 哪个方法-->
<bean id="logger" class="com.ghx.logger.Logger"/>
<bean id="bookService" class="com.ghx.service.impl.BookServiceImpl"/>
<aop:config>
<aop:aspect id="check" ref="logger">
<aop:before method="check" pointcut="execution(* *..BookServiceImpl.*(..))" />
<aop:after-returning method="logPrint" pointcut="execution(* *..BookServiceImpl.*(..))" />
<aop:after-throwing method="exception" pointcut="execution(* *..BookServiceImpl.*(..))" />
<aop:after method="distory" pointcut="execution(* *..BookServiceImpl.*(..))" />
</aop:aspect>
</aop:config>
</beans>
核心类
package com.ghx.logger;
public class Logger {
public void check(){
System.out.println("前置通知/增强- 权限验证");
}
public void logPrint(){
System.out.println("前置通知/增强- 日志输出");
}
public void exception(){
System.out.println("前置通知/增强- 异常处理");
}
public void distory(){
System.out.println("前置通知/增强- 资源释放");
}
}
测试
package com.ghx.servlet;
import com.ghx.service.Bookservice;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test01 {
public static void main(String[] args) {
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
Bookservice bookservice= context.getBean(Bookservice.class);
bookservice.findAll();
bookservice.sace(5);
bookservice.del();
bookservice.update();
}
}
结果演示: