AOP解决的问题:把横切关注点与业务逻辑相分离,即可以实现横切关注点与他们所影响的对象之间的解耦。

什么是横切关注点呢?它可以被描述为影响应用多个地方的功能。亦或者理解为辅助功能。比如日志、安全、缓存和事务管理。

1、看一下AOP的术语:

String切面可以应用5种类型的通知:前置通知,后置通知,返回通知,异常通知,环绕通知。定义了切面的什么、何时

//前置通知public void before(){System.out.println("这是前置通知!!");}//后置通知public void afterReturning(){System.out.println("这是后置通知(如果出现异常不会调用)!!");}//环绕通知public Object around(ProceedingJoinPoint pjp) throws Throwable {System.out.println("这是环绕通知之前的部分!!");Object proceed = pjp.proceed();//调用目标方法System.out.println("这是环绕通知之后的部分!!");return proceed;}//异常通知public void afterException(){System.out.println("出事啦!出现异常了!!");}//后置通知public void after(){System.out.println("这是后置通知(出现异常也会调用)!!");}

连接点:切面代码可以利用这些点插入到应用的正常流程之中,并添加新的行为。定义了切面的“何处”。

切点:有助于缩小切面通知的连接点的范围。

切面:通知和切点的结合。通知和切点定义了切面的全部内容。

引入:向现有的类添加新的方法和属性。

织入:把切面应用到目标对象并创建新的代理对象的过程。在目标对象的生命周期里有多个点可以进行织入:编译期、类加载期、运行 期。

2、Spring提供的4种类型的AOP支持:

  1. 基于代理的经典SpringAOP
  2. 纯POJO切面
  3. @AspectJ注解驱动的切面
  4. 注入式AspectJ切面

基于代理的经典SpringAOP,但是显得非常笨重和复杂。

动态代理:代理的对象必须要实现接口

只能对实现了接口的类生成代理,而不是针对类,该目标类型实现的接口都将被代理。原理是通过在运行期间创建一个接口的实现类来完成对目标对象的代理。步骤如下:

1. 定义一个实现接口InvocationHandler的类
2. 通过构造函数,注入被代理类
3. 实现invoke( Object proxy, Method method, Object[] args)方法
4. 在主函数中获得被代理类的类加载器
5. 使用Proxy.newProxyInstance( )产生一个代理对象
6. 通过代理对象调用各种方法

public class UserServiceProxyFactory implements InvocationHandler{//使用构造方法必须把us传进来public UserServiceProxyFactory(UserService us) {super();this.us = us;}private UserService us;public UserService getUserServiceProxy() {//生成动态接口代理UserService usProxy = (UserService) Proxy.newProxyInstance(UserServiceProxyFactory.class.getClassLoader(),UserServiceImpl.class.getInterfaces(), this);return usProxy;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("打开事务");Object invoke = method.invoke(us, args);System.out.println("提交事务");return invoke;}
}@Testpublic void fun1() {UserService us = new UserServiceImpl();UserServiceProxyFactory factory = new UserServiceProxyFactory(us);UserService userServiceProxy = factory.getUserServiceProxy();userServiceProxy.delete();}

CGLib代理: 实现原理通过继承目标对象来达到代理的目的,被final修饰的类不能够被代理。

public class UserServiceProxyFactory2 implements MethodInterceptor{public UserService getUserServiceProxy() {Enhancer en = new Enhancer();sCVZCZen.setSuperclass(UserServiceImpl.class);en.setCallback(this);UserService us = (UserService) en.create();return us;}@Overridepublic Object intercept(Object proxyobj, Method menhtod, Object[] arg2, MethodProxy methodProxy) throws Throwable {// 打开事务System.out.println("打开事务");// 调用原有方法Object invokeSuper = methodProxy.invokeSuper(proxyobj, arg2);// 提交事务System.out.println("提交事务");return invokeSuper;}
}@Testpublic void fun2() {UserService us = new UserServiceImpl();UserServiceProxyFactory2 factory = new UserServiceProxyFactory2();UserService userServiceProxy = factory.getUserServiceProxy();userServiceProxy.delete();}

编写切点:execution 是Spring中使用最主要的AspectJ指示器。可以使用within联用&&、||、!符号来限制匹配。

使用AspectJ切点表达式选择执行的方法,<aop:pointcut expression="execution(* Lamb_quan.service.*ServiceImpl.*(..))" id="shu"/>

在切点中选择bean: execution(* Lamb_quan.service.*ServiceImpl.*(..)) and bean(liuyifei)

                                execution(* Lamb_quan.service.*ServiceImpl.*(..)) and !bean(liuyifei)

定义切面:@Aspect注解的类不仅仅是一个普通的POJO,还是一个切面。@Pointcut注解能够在一个@Aspect切面内定义可重用的切点。

Spring使用AspectJ注解来声明通知方法:@After @AfterReturning @AfterThrowing  @Around @Before

@Pointcut注解声明频繁使用切点表达式

@Aspect

public class Audience{

@Pointcut("execution(* Lamb_quan.service.perform(..))")

public void performance () {}  //扩展切点表达式语言

@Before("performance () ")

public viod  otherMethod  () {}

}

创建环绕通知:

@Aspect

public class Audience{

@Pointcut("execution(* Lamb_quan.service.perform(..))")

public void performance () {}  //扩展切点表达式语言

@Around("performance () ")

public viod  otherMethod  (ProceedingJiontPoint jp) {

try{ 前置通知   jp.proceed(); 后置通知}catch(Throwable e){ 异常通知}

}

}

处理通知中的参数execution(* Lamb_quan.service.perform(int)) &&args(指定参数)

通过注解引入新功能:@DeclareParents注解

3、在XML中声明切面

<!-- 准备工作: 导入aop(约束)命名空间 -->
<!-- 1.配置目标对象 --><bean name="userService" class="xxx.service.UserServiceImpl" ></bean>
<!-- 2.配置通知对象 --><bean name="myAdvice" class="xxx.d_springaop.MyAdvice" ></bean>
<!-- 3.配置将通知织入目标对象 --><aop:config><!-- 配置切入点 public void xxx.service.UserServiceImpl.save() --><aop:pointcut expression="execution(* xxx.service.*ServiceImpl.*(..))" id="pc"/><aop:aspect ref="myAdvice" ><!-- 指定名为before方法作为前置通知 --><aop:before method="before" pointcut-ref="pc" /><!-- 后置 --><aop:after-returning method="afterReturning" pointcut-ref="pc" /><!-- 环绕通知 --><aop:around method="around" pointcut-ref="pc" /><!-- 异常拦截通知 --><aop:after-throwing method="afterException" pointcut-ref="pc"/><!-- 后置 --><aop:after method="after" pointcut-ref="pc"/></aop:aspect></aop:config>

为切面传递参数、通过切面引入新的功能。

4、Spring注入AspectJ切面(功能更加强大)

Spring中的面向切面(AOP)相关推荐

  1. Spring学习笔记:3(面向切面AOP)

    AOP:Aspect Oriented Program(面向切面) 我们再回顾一下AOP的一些术语: 通知(Advice) 就是你想要的功能,也就是的安全.事物.日志等.先定义好,然后在想用的地方用一 ...

  2. 微服务中的面向切面编程和更多模式

    目录 介绍 如何建立这篇文章? 在Java中使用代码(11 +,Spring boot 2.2 +,Spring Boot AOP,AspectJ) 在C#中使用代码(7,.NET MVC Core ...

  3. Spring实战4—面向切面编程

    主要内容 面向切面编程的基本知识 为POJO创建切面 使用@AspectJ注解 为AspectJ的aspects注入依赖关系 在南方没有暖气的冬天,太冷了,非常想念北方有暖气的冬天.为了取暖,很多朋友 ...

  4. 面向切面的 Spring —— 什么是面向切面编程?

    Q1:面向切面编程(AOP)解决什么问题? A1:把横切关注点与业务逻辑相分离. Q2:什么是横切关注点? A2:在软件开发中,散布于应用中多处的功能. 日志是应用切面的常见范例,但并不是切面适用的唯 ...

  5. spring中基于XML的AOP配置步骤

    spring中基于XML的AOP配置步骤 IAccountService.java package com.itheima.service;/*** 账户的业务层接口*/ public interfa ...

  6. Spring(四):面向切面编程AOP

    2019独角兽企业重金招聘Python工程师标准>>> 横切关注点:分布于应用中多处的功能 面向切面编程AOP:将横切关注点与业务逻辑相分离 在使用面向切面编程时,仍在一个地方定义通 ...

  7. Spring | 深入理解面向切面编程(AOP)

    个人主页:BoBooY的CSDN博客_Java领域博主 前言:这节我们来学习什么是面向切面编程(AOP),为了方便大家理解,我们先了解代理模式再学习AOP. 文章目录 代理模式 7.1.静态代理 7. ...

  8. spring面向切面aop拦截器

    spring中有很多概念和名词,其中有一些名字不同,但是从功能上来看总感觉是那么的相似,比如过滤器.拦截器.aop等. 过滤器filter.spring mvc拦截器Interceptor .面向切面 ...

  9. Java中的面向切面编程(AOP)

    一.什么是AOP? Aspect Oriented Programming ,即面向切面编程. AOP是对面向对象编程的一个补充. 它的目的是将复杂的需求分解为不同的切面,将散布在系统中的公共功能集中 ...

最新文章

  1. 2019.3.2 区块链论文翻译
  2. 进一步释放技术红利,阿里云推出全新内存增强型实例re6,性能提升30%
  3. 2018/7/19-纪中某C组题【jzoj3461,jzoj3462,jzoj3463,jzoj3464】
  4. 回归分析预测_使用回归分析预测心脏病。
  5. 计算机四级的英文,计算机四级考试中英文术语对照
  6. 《Python数据分析与挖掘实战》一1.2 从餐饮服务到数据挖掘
  7. Python可以这样学(第十季:网络爬虫实战)-董付国-专题视频课程
  8. mpu6050 重力加速度_MPU6050抄底解读
  9. 用C#实现基于TCP协议的网络通讯(2)
  10. BERT出来后难道我们无路可走了吗?错!这些新想法你需要了解!
  11. js 阻止冒泡 在控件的 onxxx 事件中调用就可以阻止父控件也响应消息了
  12. 2019最新北风网Ant+Java全套视频课程
  13. Java实现批量图片生成PDF文件
  14. 馈线中的VSWR电压驻波比
  15. tayga nat64优化的自省揭示tun虚拟网卡的正确玩法
  16. 干货:分析学中常用的3种分析方法!
  17. java计算机毕业设计软考刷题系统源码+mysql数据库+系统+lw文档+部署
  18. 【BZOJ 1305】[CQOI2009]dance跳舞
  19. RDP、VNC、SPICE协议性能分析之网络带宽
  20. vue实现修改用户信息的全过程

热门文章

  1. CentOS搭建Git服务器
  2. Linux命令解释之setfacl,getfacl,chattr
  3. Shell脚本的模块化和脚本复用
  4. BZOJ 4037 [HAOI2015]数字串拆分 ——动态规划
  5. 【数据结构笔记01】什么是数据结构
  6. 华中科技大学标准c语言程序设计上机试题,答案及报告格式,华中科技大学标准C语言程序设计上机试题、答案及报告格式.pdf...
  7. unity3d人物跳_Unity3D研究院之角色控制器组件研究(二十二)
  8. [置顶] 从零开始学C++之STL(二):实现简单容器模板类Vec(vector capacity 增长问题、allocator 内存分配器)...
  9. vue常用的按键修饰符
  10. 计算机出现全部英文如何解决,电脑打开后出现很多英文怎么处理