zoukankan      html  css  js  c++  java
  • JAVA框架 Spring AOP--切入点表达式和通知类型

    一:AOP的相关术语:

    1)Joinpoint(连接点):所谓的连接点是指那些可以被拦截点,在spring中这些点是指方法。因为在spring中支持方法类型的连接点。

    2)Pointcut(切入点):所谓切入点是对那些连接点进行定义(增强。)也就是说拦截点包含切入点。

    3)Advice(通知/增强):所谓通知就是拦截到joinpoint之后所要做的事情,就是通知。通知的类型分:前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)。

    4)induction(引介):引介是一种特殊的通知在不修改类的代码前提下,introduction可以在运行期动态的添加一些方法或者field。

    5)Target(目标对象): 代理的目标对象。

    6)Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程。

    7)proxy(代理):一个类被AOP织入增强后,就产生结果代理类。

    8)Aspect(切面):是切入点和通知的结合,需要我们自己编写和配置的。

    二、AOP入门

    我们使用的AOP是第三方的 aspectJ出的。所以需要整合他们的jar包。

    1)引入jar包(需要导入4个jar包)。

    需要如下jar包:

    1、spring-aop-4.2.4.RELEASE.jar ----aop的原始jar包。

    2、com.springsource.org.aopalliance-1.0.0.jar---aopalliance联盟的意思。aop联盟是针对aop制定的一些规范。如果想使用aop需要导入该jar包。

    3、com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar依赖的aspectJ的jar包。

    4、spring-aspects-4.2.4.RELEASE.jar spring本身的aspects支持的jar包。

    2)约束引入

    也之前的文件中:

    引入:

    1 <?xml version="1.0" encoding="UTF-8"?>
    2 <beans xmlns="http://www.springframework.org/schema/beans"
    3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4     xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
    5         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    6         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here -->
    7 
    8 </beans>

     3)创建包结构:

    接口:

    1 package jd.com.demo;
    2 
    3 public interface asTest {
    4     void  save();
    5     void  update();
    6 }

    实现类:

     1 package jd.com.demo;
     2 
     3 public class asTestImpl implements  asTest {
     4     @Override
     5     public void save() {
     6         System.out.println("this save method!");
     7     }
     8 
     9     @Override
    10     public void update() {
    11         System.out.println("this is update!");
    12     }
    13 }

     切面类:

    1 package jd.com.demo;
    2 
    3 public class asdemo {
    4 
    5     public void log(){
    6         System.out.println("日志输出");
    7     }
    8 }

    配置文件:

    1)实现类声明:

    1     <!--目标类的定义声明-->
    2     <bean id="asTest" class="jd.com.demo.asTestImpl"/>

    2)切面类声明:

    1     <!--切面类的定义声明-->
    2     <bean class="jd.com.demo.asdemo" id="asdemo"/>

    引入切面和需要增强方法:

    1     <aop:config  >
    2         <!--引入切面-->
    3         <aop:aspect ref="asdemo">
    4             <!--定义通知类型-->
    5             <aop:before method="log" pointcut="execution(public  void jd.com.demo.asTestImpl.save())"/>
    6         </aop:aspect>
    7     </aop:config>

     分析:

    2-->aop;before 通知类型 前置通知,即被增强的方法在执行前执行增强方法。其中method和1对应即那个切面的那个方法。

    1-->引入切面类。

    3-->pointcut 切入点那个类的那个方法需要增强 后面跟的切入点表达式 。 修饰符  返回值  类的全路径  方法 用属性点连接。

     3)切入点表达式:

     1        <bean id="asTest" class="jd.com.demo.asTestImpl"/>
     2       <bean class="jd.com.demo.asdemo" id="asdemo"/>
     3         <aop:config  >
     4            <aop:aspect ref="asdemo"> 
     5             <!--1、execution()固定写法-->
     6             <!--<aop:before method="log" pointcut="execution(public  void jd.com.demo.asTestImpl.save())"/>-->
     7             <!--
     8             2、修饰符public可以省略
     9             <aop:before method="log" pointcut="execution(  void jd.com.demo.asTestImpl.save())"/>-->
    10             <!--
    11             3、返回值 可以写任意类型,比如:void 、String 会根据返回值得类型去匹配需要加强的类。
    12                 匹配任意类型* 该值不可以省略。
    13             <aop:before method="log" pointcut="execution(  * jd.com.demo.asTestImpl.save())"/>-->
    14             <!--
    15             4、包路径可以省略,用*代替。但是只代表一层(*.asTestImpl 表示src下面的一层目录下面的实现类)。包的名字可以写成*Impl 表示以什么结尾 同样方法也可以这么写:*save 表示以save结尾的方法。
    16             <aop:before method="log" pointcut="execution(  * *.*.*.*Impl.*save())"/>-->
    17             <!--
    18             4、方法的参数可以省略.. 表示任意参数。
    19             <aop:before method="log" pointcut="execution(  * *.*.*.*Impl.*save(..))"/>-->
    20             </aop:aspect>
    21          </aop:config>

     注意:

    再注入被加强的类的时候,设置字段的时候,类型需要写成接口的类型!!!!

     4)通知类型:

    1:前置通知 在方法运行前运行,可以对方法的参数来做校验。

    1 <aop:before method="log" pointcut="execution(  * *.*.*.*Impl.*save())"/>

     2:最终通知类型通知,无论方法执行失败还是成功,都会在原先方法执行完之后执行。该类型可以用于一些资源的释放。、

    1   <aop:after method="after" pointcut="execution(  * *.*.*.*Impl.*save())"/>

    3、后置通知 方法正常执行,才执行,一般用于方法成功执行的时候,对结果做一些简单的处理。

    1 <aop:after-returning method="afterreturning" pointcut="execution(  * *.*.*.*Impl.*save())"/>

     4、异常通知:当被增强的方法,出现异常的时候,执行。

    1    <aop:after-throwing method="afterthrowing" pointcut="execution(  * *.*.*.*Impl.*save())"/>

    5、环绕通知:在使用该通知的时候,如果不手动开启执行被增强方法的话。增强方法不会被执行。需要手动传入参数:ProceedingJoinPoint proceedingJoinPoint 然后执行: proceedingJoinPoint.proceed()。

    1  <aop:around method="afteraround" pointcut="execution(  * *.*.*.*Impl.*save())"/>
    1     public  void  afteraround(ProceedingJoinPoint proceedingJoinPoint){
    2         System.out.println("环绕通知.");
    3         try {
    4             proceedingJoinPoint.proceed();
    5         } catch (Throwable throwable) {
    6             throwable.printStackTrace();
    7         }
    8         System.out.println("环绕通知.");
    9     }

     切面代码:

     1 package jd.com.demo;
     2 
     3 import org.aspectj.lang.ProceedingJoinPoint;
     4 
     5 public class asdemo {
     6 
     7     public void log(){
     8         System.out.println("日志输出");
     9     }
    10     public  void  after(){
    11         System.out.println("最终类型通知!");
    12     }
    13     public void afterreturning(){
    14         System.out.println("后置类型通知");
    15     }
    16     public  void  afterthrowing(){
    17         System.out.println("后置异常通知.");
    18     }
    19     public  void  afteraround(ProceedingJoinPoint proceedingJoinPoint){
    20         System.out.println("环绕通知.");
    21         try {
    22             proceedingJoinPoint.proceed();
    23         } catch (Throwable throwable) {
    24             throwable.printStackTrace();
    25         }
    26         System.out.println("环绕通知.");
    27     }
    28 }
  • 相关阅读:
    HTML基础(一)基本语法知识
    本地方法接口
    本地方法栈
    虚拟机栈相关的问题
    栈帧的内部结构--一些附加信息
    基于角色的权限控制设计
    SpringBoot普通消息队列线程池配置
    栈帧的内部结构--动态返回地址(Return Address)
    栈帧的内部结构--动态链接 (Dynamic Linking)
    栈帧的内部结构--操作数栈(Opreand Stack)
  • 原文地址:https://www.cnblogs.com/evilliu/p/8875852.html
Copyright © 2011-2022 走看看