本文源码:GitHub·点这里 || GitEE·点这里

一、AOP基础简介

1、切面编程简介

AOP全称:Aspect Oriented Programming,面向切面编程。通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。核心作用:可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的复用性和开发效率。AOP提供了取代继承和委托的一种新的方案,而且使用起来更加简洁清晰,是软件开发中的一个热点理念。

2、AOP术语

(1)、通知类型:Advice

前置通知[Before]:目标方法被调用之前; 返回通知[After-returning]:目标方法执行成功之后; 异常通知[After-throwing]:在目标方法抛出异常之后;  后置通知[After]:目标方法完成之后; 环绕通知[Around]:在目标方法执行前后环绕通知;

(2)、连接点:JoinPoint

程序执行的某一个特定位置,如类初始前后,方法的运行前后。

(3)、切点:Pointcut

连接点是指那些在指定策略下可能被拦截到的方法。

(4)、切面:Aspect

切面由切点和通知的结合。

(5)、引入:Introduction

特殊的增强,为类添加一些属性和方法。

(6)、织入:Weaving

将增强添加到目标类的具体连接点上的过程。编译期织入,这要求使用特殊编译器;类装载期织入,这要求使用特殊的类加载器;动态代理织入,在运行期为目标类添加增强生成子类的方式,Spring采用的是动态代理织入,而AspectJ采用编译期织入和类装载期织入。

(7)、代理:Proxy

类被AOP织入后生成一个结果类,它是融合了原类和增强逻辑的代理类。

二、AOP编程实现方式

案例基于如下类进行:

public class Book {     private String bookName ;     private String author ; } public interface BookService {     void addBook (Book book) ; } public class BookServiceImpl implements BookService {     @Override     public void addBook(Book book) {         System.out.println(book.getBookName());         System.out.println(book.getAuthor());     } }

1、JDK动态代理

public class BookAopProxyFactory {     public static BookService createService() {         // 目标类         final BookService bookService = new BookServiceImpl() ;         // 切面类         final BookAspect bookAspect = new BookAspect();         /*          * 代理类:将目标类(切入点)和 切面类(通知) 结合          */         BookService proxyBookService = (BookService) Proxy.newProxyInstance(                 BookAopProxyFactory.class.getClassLoader(),                 bookService.getClass().getInterfaces(),                 new InvocationHandler() {                     public Object invoke(Object proxy, Method method,                                          Object[] args) throws Throwable {                         // 前执行                         bookAspect.before();                         // 执行目标类的方法                         Object obj = method.invoke(bookService, args);                         // 后执行                         bookAspect.after();                         return obj;                     }                 });         return proxyBookService ;     } }

2、CgLib字节码增强

采用字节码增强框架cglib,在运行时创建目标类的子类,从而对目标类进行增强。

public class BookAopCgLibFactory {     public static BookService createService() {         //