本文源码: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 {@Overridepublic 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() {// 目标类final BookService bookService = new BookServiceImpl() ;// 切面类final BookAspect bookAspect = new BookAspect();// 核心代理类Enhancer enhancer = new Enhancer();// 确定父类enhancer.setSuperclass(bookService.getClass());// 设置回调函数enhancer.setCallback(new MethodInterceptor() {public Object intercept(Object proxy, Method method,Object[] args,MethodProxy methodProxy) throws Throwable {bookAspect.before();Object obj = method.invoke(bookService, args);bookAspect.after();return obj;}});BookServiceImpl proxyService = (BookServiceImpl) enhancer.create();return proxyService ;}
}

3、Spring半自动代理

spring 创建代理对象,从spring容器中手动的获取代理对象。

  • 配置文件
<!-- 创建目标类 -->
<bean id="bookService" class="com.spring.mvc.service.impl.BookServiceImpl" />
<!-- 创建切面类 -->
<bean id="myAspect" class="com.spring.mvc.config.BookAopSpringHalf" />
<!-- 创建代理类 -->
<bean id="proxyFactory" class="org.springframework.aop.framework.ProxyFactoryBean"><property name="interfaces" value="com.spring.mvc.service.BookService" /><property name="target" ref="bookService" /><property name="interceptorNames" value="myAspect" />
</bean>
  • 切面类
public class BookAopSpringHalf implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation methodInvocation) throws Throwable {System.out.println("Method Before ...");Object obj = methodInvocation.proceed();System.out.println("Method After ...");return obj;}
}

4、Spring全自动代理

从spring容器获得目标类,如果配置Aop,spring将自动生成代理。

  • 配置文件
<!-- 创建目标类 -->
<bean id="bookService" class="com.spring.mvc.service.impl.BookServiceImpl" />
<!-- 创建切面类 -->
<bean id="myAspect" class="com.spring.mvc.config.BookAopSpringHalf" />
<!-- AOP编程配置 -->
<aop:config proxy-target-class="true"><aop:pointcut expression="execution(* com.spring.mvc.service.*.*(..))"id="myPointCut"/><aop:advisor advice-ref="myAspect" pointcut-ref="myPointCut"/>
</aop:config>

5、综合测试

@Test
public void test1 (){BookService bookService = BookAopProxyFactory.createService() ;Book book = new Book() ;book.setBookName("Spring实战");book.setAuthor("Craig Walls");bookService.addBook(book);
}
@Test
public void test2 (){BookService bookService = BookAopCgLibFactory.createService() ;Book book = new Book() ;book.setBookName("MySQL");book.setAuthor("Baron");bookService.addBook(book);
}
@Test
public void test3 (){String xmlPath = "spring-aop-half.xml";ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(xmlPath);BookService bookService = (BookService) context.getBean("proxyFactory");Book book = new Book() ;book.setBookName("红楼梦");book.setAuthor("曹雪芹");bookService.addBook(book);
}
@Test
public void test4 (){String xmlPath = "spring-aop-all.xml";ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(xmlPath);BookService bookService = (BookService) context.getBean("bookService");Book book = new Book() ;book.setBookName("西游记");book.setAuthor("吴承恩");bookService.addBook(book);
}

三、AspectJ切面编程

1、基础简介

AspectJ是一个基于Java语言的AOP框架,Spring2.0以后新增了对AspectJ切点表达式支持,通过JDK5注解技术,允许直接在类中定义切面,新版本Spring框架,推荐使用AspectJ方式来开发AOP编程。

2、XML配置方式

  • 切面类
public class BookAopAspectJ {public void myBefore(JoinPoint joinPoint){System.out.println("前置通知:" + joinPoint.getSignature().getName());}public void myAfterReturning(JoinPoint joinPoint,Object ret){System.out.println("后置通知:" + joinPoint.getSignature().getName() + " , -->" + ret);}public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{System.out.println("环绕通知前");Object obj = joinPoint.proceed();System.out.println("环绕通知前后");return obj;}public void myAfterThrowing(JoinPoint joinPoint,Throwable e){System.out.println("抛出异常通知 : " + e.getMessage());}public void myAfter(JoinPoint joinPoint){System.out.println("最终通知");}
}
  • 配置文件
<!-- 创建目标类 -->
<bean id="bookService" class="com.spring.mvc.service.impl.BookServiceImpl" />
<!-- 创建切面类 -->
<bean id="myAspect" class="com.spring.mvc.config.BookAopAspectJ" />
<!-- 配置AOP编程 -->
<aop:config><aop:aspect ref="myAspect"><aop:pointcut expression="execution(* com.spring.mvc.service.impl.BookServiceImpl.*(..))" id="myPointCut"/><!-- 前置通知--><aop:before method="myBefore" pointcut-ref="myPointCut"/><!-- 后置通知 --><aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="ret" /><!-- 环绕通知 --><aop:around method="myAround" pointcut-ref="myPointCut"/><!-- 抛出异常 --><aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointCut" throwing="e"/><!-- 最终通知 --><aop:after method="myAfter" pointcut-ref="myPointCut"/></aop:aspect>
</aop:config>
  • 测试方法
@Test
public void test1 (){String xmlPath = "spring-aop-aspectj-01.xml";ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(xmlPath);BookService bookService = (BookService) context.getBean("bookService");Book book = new Book() ;book.setBookName("三国演义");book.setAuthor("罗贯中");bookService.addBook(book);
}

3、注解扫描方式

  • 配置文件
<!-- 开启类注解的扫描 -->
<context:component-scan base-package="com.spring.mvc.service.impl" />
<!-- 确定AOP注解生效 -->
<aop:aspectj-autoproxy />
<!-- 声明切面 -->
<bean id="myAspect" class="com.spring.mvc.config.AuthorAopAspectJ" />
<aop:config><aop:aspect ref="myAspect" />
</aop:config>
  • 注解切面类
@Component
@Aspect
public class AuthorAopAspectJ {@Pointcut("execution(* com.spring.mvc.service.impl.AuthorServiceImpl.*(..))")private void myPointCut(){}@Before("execution(* com.spring.mvc.service.impl.AuthorServiceImpl.*(..))")public void myBefore(JoinPoint joinPoint){System.out.println("前置通知:" + joinPoint.getSignature().getName());}@AfterReturning(value="myPointCut()" ,returning="ret")public void myAfterReturning(JoinPoint joinPoint,Object ret){System.out.println("后置通知:" +joinPoint.getSignature().getName() + " , -->" + ret);}@Around(value = "myPointCut()")public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{System.out.println("环绕通知前");Object obj = joinPoint.proceed();System.out.println("环绕通知前后");return obj;}@AfterThrowing(value="execution(* com.spring.mvc.service.impl.AuthorServiceImpl.*(..))",throwing="e")public void myAfterThrowing(JoinPoint joinPoint,Throwable e){System.out.println("抛出异常通知 : " + e.getMessage());}@After("myPointCut()")public void myAfter(JoinPoint joinPoint){System.out.println("最终通知");}
}
  • 测试方法
@Test
public void test2 (){String xmlPath = "spring-aop-aspectj-02.xml";ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(xmlPath);AuthorService authorService = (AuthorService) context.getBean("authorService");System.out.println("作者:"+authorService.getAuthor());
}

四、源代码地址

GitHub·地址
https://github.com/cicadasmile/spring-mvc-parent
GitEE·地址
https://gitee.com/cicadasmile/spring-mvc-parent

Spring 框架基础(04):AOP切面编程概念,几种实现方式演示相关推荐

  1. Spring中的AOP切面编程的三种实现方式

    文章目录 Spring中的AOP切面编程的三种实现方式 1.最基本AOP的实现 a.引入jar包 b.编写通知类,这里以后置通知和环绕通知类为例子进行说明 c.在SpringIOC容器中配置 d.测试 ...

  2. AOP面向切面编程的三种实现方式

    AOP概念 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是 ...

  3. Spring 框架基础(05):事务管理机制,和实现方式

    本文源码:GitHub·点这里 || GitEE·点这里 一.Spring事务管理 1.基础描述 Spring事务管理的本质就是封装了数据库对事务支持的操作,使用JDBC的事务管理机制,就是利用jav ...

  4. Aop切面编程原理和Spring实现

    Aop切面编程概念 AOP切面编程一般可以帮助我们在不修改现有代码的情况下,对程序的功能进行拓展,往往用于实现 日志处理,权限控制,性能检测,事务控制等 AOP实现的原理就是动态代理,在有接口的情况下 ...

  5. SpringBoot2.0 基础案例(11):配置AOP切面编程,解决日志记录业务

    本文源码 GitHub地址:知了一笑 https://github.com/cicadasmile/spring-boot-base 一.AOP切面编程 1.什么是AOP编程 在软件业,AOP为Asp ...

  6. 一.Spring框架基础

    JAVAEE框架之Spring 一.Spring框架基础 Spring:春天:轻量级的企业级开发框架,核心是IOC(控制反转)和AOP(面向切面编程). 官网:spring.io Spring–> ...

  7. 2022年Java应届生面试之Spring框架基础知识

    前言:工作的原因,最近没有及时更新相关系列.很抱歉!在复习Spring框架的同时也别忘了j2ee的相关知识理论wo~ 大家好!我是JAVA 中的Spring框架,我是一个开源的容器性质的轻量级框架. ...

  8. Spring框架基础入门

    文章目录 一.Spring概述与环境搭建 Spring环境搭建 二.控制反转IoC 三.多种方式实现依赖注入 1.属性注入 基本数据类型 注入对象类型 注入集合和数组类型 2.构造方法注入 按类型注入 ...

  9. java切面类整合_SpringBoot2.x【五】整合AOP切面编程

    SpringBoot2.x[五]整合AOP切面编程 面向方面编程(AOP)通过提供另一种思考程序结构的方式来补充面向对象编程(OOP). OOP中模块化的关键单元是类,而在AOP中,模块化单元是方面. ...

最新文章

  1. Pandas 基础 (1)—— Series
  2. MASM32_SDKv10以及一些帮大家打包的东西
  3. MapReduce源码之InputFormat
  4. 针对Python中冒号的详细解释
  5. UNIX再学习 -- 可重入函数和 SIGCHLD 语义
  6. ajax 中Accordion控件的使用
  7. 测量怎么显示坐标_测量员必须掌握的——全站仪坐标放样
  8. Keepalived+nginx+redis主从+tomcat一机多实例实现会话共享
  9. java用来存储键值的容器是_Java容器 - osc_y0caef0i的个人空间 - OSCHINA - 中文开源技术交流社区...
  10. [HNOI2011]数学作业 题解
  11. 代码性能JavaScript性能优化总结
  12. unity设置一个物体是另一个物体的子物体
  13. 【开发工具集】功能强大的网络设置工具——IPOP
  14. Python基础之文件操作
  15. QT中的.pro文件,以及.pri .prj .prl文件说明
  16. 基于深度学习时间序列分类研究综述[论文阅读]
  17. cesium 贴地+空间+面积测量
  18. 取消Editplus的自动备份
  19. 史上最全的程序员求职渠道总结
  20. 阿里800k大数据工程师讲述:什么是大数据未来大数据的就业前景?

热门文章

  1. 操作系统之计算机系统概述:1、操作系统概述(定义、功能、作用)
  2. 27. 二叉树的镜像
  3. libwacom9 : Depends: libwacom-common (= 2.2.0-1) but 1.12-1 is to be installed
  4. Max retries exceeded with url
  5. twisted系列教程十六–twisted守护进程
  6. Windows驱动—64位驱动测试64位驱动测试签名
  7. 排序算法:希尔排序算法实现及分析
  8. PHP 文件夹操作「复制、删除、查看大小」递归实现
  9. Largest Number 179
  10. Velocity语法参考