Spring框架内容整理(三):AOP

news/2024/7/7 21:12:55

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

AOP面向切面

切面支持类

切面就是通知和切入点的组合,而切面是通过配置方式定义的,因此这定义切面前,我们需要定义切面支持类,切面支持类提供了通知实现

package cn.javass.spring.chapter6.aop;
public class HelloWorldAspect {
    //前置通知
    public void beforeAdvice() {
        System.out.println("===========before advice");
    }
    //后置最终通知
    public void afterFinallyAdvice() {
        System.out.println("===========after finally advice");
    }
}

HelloWorldAspect类不是真正的切面实现,只是定义了通知实现的类,在此我们可以把它看作就是缺少了切入点的切面。

Schema XML配置AOP

1)首先配置AOP需要aop命名空间

<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation=".....
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
</ beans>

2)配置目标类:

< bean id="helloWorldService" class="cn.javass.spring.chapter6.service.impl.HelloWorldService"/>
  • 1

3)配置切面:

<!--切面支持类-->
<bean id="aspect" class="cn.javass.spring.chapter6.aop.HelloWorldAspect"/> //
<aop:config>
    <!-- 切点 -->
    <aop:pointcut id="pointcut" expression="execution(* cn.javass..*.*(..))"/>
    <!-- 切面 -->
    <aop:aspect ref="aspect">
        <!-- 前置通知 -->
        <aop:before pointcut-ref="pointcut" method="beforeAdvice"/>
        <!-- 后置最终通知 -->
        <aop:after pointcut="execution(* cn.javass..*.*(..))" method="afterFinallyAdvice"/>
    </aop:aspect>
</aop:config>

配置解析: 
< aop:pointcut>:用来定义切入点,该切入点可以重用; expression属性:定义切入点模式,默认是AspectJ语法, 
< aop:aspect>:切面,其中“ref”用来引用切面支持类的方法 
< aop:before>:前置通知,pointcut-ref属性用于引用切入点Bean,而method用来引用切面 
通知实现类中的方法,该方法就是通知实现,即在目标类方法执行之前调用的方法。 
< aop:after >:后置通知,除了使用pointcut-ref属性来引用已经存在的切入点,也可以使用pointcut属性来定义,如pointcut=”execution(* cn.javass...(..))”,method属性同样是指定通知实现,即在目标类方法执行之后调用的方法。

这里写图片描述

Spring AOP框架生成AOP代理过程

Spring AOP框架生成AOP代理过程

 

AOP配置解析

切面

切面就是包含切入点和通知的对象,在Spring容器中将被定义为一个Bean该支持Bean的字段和方法提供了切面的状态和行为信息,并通过配置方式来指定切入点和通知实现。

切面使用< aop:aspect>标签指定,ref属性用来引用切面支持Bean。

切点

在< aop:config>标签下使用< aop:pointcut>声明一个切入点Bean,该切入点可以被多个切面使用,expression属性指定切入点表达式

匿名切入点Bean,可以在声明通知时通过pointcut属性指定切入点表达式,该切入点是匿名切入点,只被该通知使用

<aop:config>
    <aop:aspect ref="aspectSupportBean">
        <aop:after pointcut="execution(* cn.javass..*.*(..))" method="afterFinallyAdvice"/>
    </aop:aspect>
</aop:config>
  • 1
  • 2
  • 3
  • 4
  • 5

声明通知

前置通知:在切入点选择的方法之前执行,通过< aop:aspect>标签下的< aop:before>标签声明:

<bean id="helloWorldService"
    class="cn.javass.spring.chapter6.service.impl.HelloWorldService"/>
<bean id="aspect" class="cn.javass.spring.chapter6.aop.HelloWorldAspect"/>
<aop:config>
    <aop:aspect ref="aspect">
    <aop:before pointcut="execution(* cn.javass..*.sayBefore(..)) and args(param)"
        method="beforeAdvice(java.lang.String)" arg-names="param"/>
    </aop:aspect>
</aop:config>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

使用“args(param)”匹配目标方法只有一个参数且传入的参数类型为通知实现方法中同名的参数类型 
使用method=” beforeAdvice(java.lang.String) “指定前置通知实现方法,且该通知有一个参数类型为java.lang.String参数;

后置返回通知 
在切入点选择的方法正常返回时执行,通过< aop:aspect>标签下的< aop:after-returning>标签声明:

<aop:after-returning pointcut="切入点表达式" pointcut-ref="切入点Bean引用"
    method="后置返回通知实现方法名"
    arg-names="后置返回通知实现方法参数列表参数名字"
    returning="返回值对应的后置返回通知实现方法参数名"
/>
  • 1
  • 2
  • 3
  • 4
  • 5

returning:定义一个名字,该名字用于匹配通知实现方法的一个参数名,当目标方法执行正常返回后,将把目标方法返回值传给通知方 法;returning限定了只有目标方法返回值匹配与通知方法相应参数类型时才能执行后置返回通知,否则不执行,对于returning对应的通知方法 参数为Object类型将匹配任何目标返回值

AspectJ方式配置AOP

Spring除了支持Schema方式配置AOP,还支持注解方式:使用@AspectJ风格的切面声明 
Spring默认不支持@AspectJ风格的切面声明,开启配置 
< aop:aspectj-autoproxy/>

切面

使用@Aspect注解进行声明

@Aspect()
Public class Aspect{
    .....
}
<bean id="aspect" class="……Aspect"/>
  • 1
  • 2
  • 3
  • 4
  • 5

切点

@Pointcut+方法(方法必须是返回void类型)实现

@Pointcut(value=”切入点表达式”, argNames = “参数名列表”) 
public void pointcutName(……) {}

  • value:指定切入点表达式;
  • argNames:指定命名切入点方法参数列表参数名字,可以有多个用“,”分隔,这些参数将传递给通知方法同名的参数,同时比如切入点表达式“args(param)”将匹配参数类型为命名切入点方法同名参数指定的参数类型。
  • pointcutName:切入点名字,可以使用该名字进行引用该切入点表达式。
@Pointcut(value="execution(* cn.javass..*.sayAdvisorBefore(..)) && args(param)", argNames = "param")
public void beforePointcut(String param) {}
  • 1
  • 2

声明通知

一、前置通知

@Before(value = "切入点表达式或命名切入点", argNames = "参数列表参数名")
@Before(value = "beforePointcut(param)", argNames = "param")
public void beforeAdvice(String param) {
    System.out.println("===========before advice param:" + param);
}
  • 1
  • 2
  • 3
  • 4
  • 5

二、后置返回通知

/*
    value:指定切入点表达式或命名切入点;
    pointcut:同样是指定切入点表达式或命名切入点,如果指定了将覆盖value属性指定的,pointcut具有高优先级;
    argNames:与Schema方式配置中的同义;
    returning:与Schema方式配置中的同义。
*/
@AfterReturning(
    value="切入点表达式或命名切入点",
    pointcut="切入点表达式或命名切入点",
    argNames="参数列表参数名",
    returning="返回值对应参数名")       
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

切面、切入点、通知全部使用注解完成: 
1)使用@Aspect将POJO声明为切面; 
2)使用@Pointcut进行命名切入点声明, 
3)使用@Before进行前置通知声明,其中value用于定义切入点表达式或引用命名切入点; 
4)配置文件需要使用< aop:aspectj-autoproxy/>来开启注解风格的@AspectJ支持; 
5)需要将切面注册为Bean,如“aspect”Bean;

expression类型匹配语法 
* :匹配任何数量字符; 
.. :(两个点)匹配任何数量字符的重复,如在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数。 
+ : 匹配指定类型的子类型;仅能作为后缀放在类型模式后边

这里写图片描述

Spring代理机制

这里写图片描述

转载于:https://my.oschina.net/architectliuyuanyuan/blog/1619339


http://www.niftyadmin.cn/n/3778341.html

相关文章

python并发编程之多进程理论

一、什么是进程 进程&#xff1a;正在进行的一个过程或者说一个任务。而负责执行任务则是cpu。 举例&#xff1a;单核多道&#xff0c;实现多个进程的并发执行你在一个时间段内有很多任务要做&#xff1a;写python程序&#xff0c;打游戏&#xff0c;逛淘宝  但你同一时刻只能…

python堆排序

堆排序介绍 堆排序&#xff0c;顾名思义&#xff0c;就是基于堆。因此先来介绍一下堆的概念。 堆分为最大堆和最小堆&#xff0c;其实就是完全二叉树。最大堆要求节点的元素都要大于其孩子&#xff0c;最小堆要求节点元素都小于其左右孩子&#xff0c;两者对左右孩子的大小关系…

005-统一沟通-部署-基础-环境

准备Active Directory 和域(031-Mail01)安装完成(031-Mail01)为邮箱服务器创建DNS记录&#xff08;011-DC01&#xff09;验证DNS邮箱服务器安装证书&#xff08;031-Mail01&#xff09;前端服务器验证林准备和域&#xff08;011-DC01&#xff09;前端服务器DNS验证&#xff08;…

Shiro整合springboot,freemaker,redis

为什么80%的码农都做不了架构师&#xff1f;>>> 一、导语 今天推荐给大家一个非常简单&#xff0c;实用的开源权限框架&#xff1a;Shiro&#xff0c;这也是Java官方推荐的权限框架。 尽管网上有很多类似的文章&#xff0c;但是都不够完善&#xff0c;尤其是涉及到…

微软超融合私有云测试32-SCCM2016部署之SCCM管理服务器安装

1&#xff09; 前置条件安装完毕后&#xff0c;插入SCCM安装光盘&#xff0c;打开安装光盘的如下路径下的extadsh.exe程序并执行&#xff0c;&#xff08;注意&#xff1a; 一定要从CMD中执行&#xff0c;并且使用管理员模式&#xff09;\SMSSETUP\BIN\X642&#xff09; 执行成…

xgboost小试

2019独角兽企业重金招聘Python工程师标准>>> 1. virtualenv 创建一个虚拟环境 virtualenv xgboost-env cd xgboost-env 2. 下载代码 git clone --recursive https://github.com/dmlc/xgboost --recursive : 下载所有关联的包 3. 编译 cd xgboost make -j4“-j4”是4…

记录java虚拟机性能监控工具(jps与jstat)的使用

(1) jps(Java Virtual Machine Process Status) 虚拟机进程状况工具;1.1 显示运行的Java应该程序的进程IDjps -q#86589#775671.2 显示运行的Java应该程序的进程ID及类名jps #86533 Jps#77567 Bootstrap1.3 显示运行的Java应该程序的进程ID及类全名jps -l#86701 sun.tools.jps.J…

挂载报错:“/dev/vda1 is apparently in use by the system;”

挂载报错&#xff1a;“/dev/vda1 is apparently in use by the system;” 作者&#xff1a;尹正杰 版权声明&#xff1a;原创作品&#xff0c;谢绝转载&#xff01;否则将追究法律责任。 距离回家倒计时还有一天&#xff0c;明天中午的火车就回老家了&#xff0c;想想还是蛮开…