热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

AOP简介及前置通知和后置通知的使用

AOP面向切面编程AspectsOrientedProgrammer正常程序执行流程都是纵向执行,面向切面编程是在原有纵向执行流程中,针对某一个或一些

AOP


  • 面向切面编程 Aspects Oriented Programmer
  • 正常程序执行流程都是纵向执行,面向切面编程是在原有纵向执行流程中,针对某一个或一些方法添加通知,形成横切面的过程
  • 不需要修改原有的代码
  • 高扩展性,原有功能相当于释放了部分逻辑,让职责更加明确

常用概念


  • 原有功能:切点 pointcut
  • 前置通知:在切点之前执行的功能 before advice
  • 后置通知:在切点之后执行的功能 after advice
  • 如果在切点执行过程中出现乙城,会触发异常通知 throws advice

Spring的两种实现AOP方式


  • Schame-based
    • 每个通知都要实现接口或类
    • 配置 spring 配置文件时在 配置
  • AspectJ
    • 每个通知不需要实现接口或类
    • 在 spring 配置文件 的子标签 中配置

Schema-based


  • 导入 jar 包,spring 四个核心包、日志包、aop及依赖包
    jar

  • 新建前置通知类

public class MyBeforeAdvice implements MethodBeforeAdvice{// 必须要实现改接口/*** 切点方法对象 Method 对象* 切点方法参数* 方法所在对象*/@Overridepublic void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {System.out.println("执行前置方法!");}}

  • 后置通知类

public class MyAfterAdvice implements AfterReturningAdvice{/***切点方法返回值,切点方法对象,切点方法参数,切点方法所在类的对象*/@Overridepublic void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {System.out.println("后置方法");System.out.println(arg0);System.out.println(arg1.getName());System.out.println(arg2);System.out.println(arg3);}}

  • 所在类对象

public class Demo {public void demo1() {System.out.println("demo1");}public void demo2() {System.out.println("demo2");}public void demo3() {System.out.println("demo3");}// 有参public void demo4(String str) {System.out.println("demo4");}// 有参,有返回值public String demo5(String str) {System.out.println("demo5");return str;}}

  • spring 配置文件
    • 引入 aop 命名空间
    • 配置通知类的 bean
    • 配置切面


<beans xmlns&#61;"http://www.springframework.org/schema/beans"xmlns:xsi&#61;"http://www.w3.org/2001/XMLSchema-instance"xmlns:aop&#61;"http://www.springframework.org/schema/aop"xsi:schemaLocation&#61;"http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><bean id&#61;"mybefore" class&#61;"com.mak.advice.MyBeforeAdvice">bean><bean id&#61;"myafter" class&#61;"com.mak.advice.MyAfterAdvice">bean><aop:config><aop:pointcut expression&#61;"execution(* com.mak.test.Demo.demo2())" id&#61;"mypoint"/><aop:advisor advice-ref&#61;"mybefore" pointcut-ref&#61;"mypoint"/><aop:advisor advice-ref&#61;"myafter" pointcut-ref&#61;"mypoint"/>aop:config><bean id&#61;"demo" class&#61;"com.mak.test.Demo">bean>beans>

  • 测试

public class Test {public static void main(String[] args) {ApplicationContext ac &#61; new ClassPathXmlApplicationContext("applicationContext.xml");Demo demo &#61; ac.getBean("demo", Demo.class);demo.demo1();demo.demo2();demo.demo3();}}

demo1
执行前置方法&#xff01;
demo2 // 切点方法对象
[Ljava.lang.Object;&#64;71529963 // 切点方法参数
com.mak.test.Demo&#64;61a88b8c //切点所在类对象
demo2
后置方法
null // 切点方法返回值 demo2 没有返回值
demo2 // 七点方法对象
[Ljava.lang.Object;&#64;71529963 // 参数
com.mak.test.Demo&#64;61a88b8c // 所在类对象
demo3

通配符&#xff08;*&#xff09;的使用

// 表示 为 test 包下的 Demo 类中 所有的方法 添加切面
<aop:pointcut expression&#61;"execution(* com.mak.test.Demo.*())" id&#61;"mypoint"/>// 表示 为 test 下的所有类中的所有方法 添加切面
<aop:pointcut expression&#61;"execution(* com.mak.test.*.*())" id&#61;"mypoint"/>// (..) 匹配任意方法参数 有参数要添加
<aop:pointcut expression&#61;"execution(* com.mak.test.*.*(..))" id&#61;"mypoint"/>

推荐阅读
author-avatar
ColinYinbaohua
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有