zoukankan      html  css  js  c++  java
  • 前置通知

    【Spring AOP】

    1.AspectJ:Java社区里最完整最流行的AOP框架。

    2.在Spring2.0 以上的版本中,可以使用基于AspectJ注解或基于XML配置的AOP。

    【在Spring中启用AspectJ注解支持】

    1.要在Spring应用中使用AspectJ注解,必须在classpath下包含AspectJ类库:aopalliance.jar、aspectj.weaver.jar和spring-aspects.jar。

    2.将aop Schema添加到<beans>根元素中

    3.要在Spring IOC容器中启用AspectJ注解支持,只要在Bean配置文件中定义一个空的XML元素<aop:aspectj-autoproxy>。

    4.当Spring IOC容器侦测到Bean配置文件中的<aop:aspectj-autoproxy>元素时,会自动为与AspectJ切面匹配的Bean创建代理。

    【用AspectJ注解声明切面】

    1.要在Spring中声明AspectJ切面,只需要在IOC容器中将切面声明为Bean实例。当在Spring IOC容器中初始化AspectJ切面之后,Spring IOC 容器就会为那些与AspectJ切面相匹配的Bean创建代理。

    2.在AspectJ注解中,切面只是一个带有@Aspect注解的Java类

    3.通知是标注有某种注解的简单的Java方法

    4.AspectJ支持5种类型的通知注解:

    --@Before:前置通知,在方法执行之前执行

    --@After:后置通知,在方法执行之后执行

    --@AfterRunning:返回通知,在方法返回结果之后执行

    --@AfterThrowing:异常通知,在方法抛出异常之后

    --@Around:环绕通知,围绕着方法执行 

    实现:在result结果输出前会有一个提示语句输出。

    LoggingAspect.java:

     1 package com.hk.spring.aop.impl;
     2 
     3 import java.util.Arrays;
     4 import java.util.List;
     5 import org.aspectj.lang.JoinPoint;
     6 import org.aspectj.lang.annotation.Aspect;
     7 import org.aspectj.lang.annotation.Before;
     8 import org.springframework.stereotype.Component;
     9 
    10 //把这个类声明为一个切面。步骤:需要把该类放入到IOC容器中,然后再声明为一个切面。
    11 @Aspect
    12 @Component
    13 public class LoggingAspect {
    14     //声明该方法是一个前置通知:在目标方法之前执行
    15     @Before("execution(public int com.hk.spring.aop.impl.ArithmeticCalculator.add(int,int))")
    16     public void beforeMethod(JoinPoint joinPoint){
    17         String methodName = joinPoint.getSignature().getName();
    18         List<Object> args = Arrays.asList(joinPoint.getArgs());
    19         System.out.println("The method " + methodName + " begins with " + args);
    20     }
    21 }

    applicationContext.xml:

     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"
     5     xmlns:context="http://www.springframework.org/schema/context"
     6     xsi:schemaLocation="http://www.springframework.org/schema/beans 
     7         http://www.springframework.org/schema/beans/spring-beans.xsd
     8         http://www.springframework.org/schema/context 
     9         http://www.springframework.org/schema/context/spring-context-4.3.xsd
    10         http://www.springframework.org/schema/aop 
    11         http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
    12 
    13   <!-- 配置自动扫描的包 -->
    14   <context:component-scan base-package="com.hk.spring.aop.impl"></context:component-scan>
    15   
    16   <!-- 使AspectJ 注解起作用:自动为匹配的类生成代理对象 -->
    17   <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    18 </beans>

    Main.java:

     1 package com.hk.spring.aop.impl;
     2 
     3 import org.springframework.context.ApplicationContext;
     4 import org.springframework.context.support.ClassPathXmlApplicationContext;
     5 
     6 public class Main {
     7     public static void main(String[] args) {
     8         //1.创建Spring的IOC容器
     9         ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    10         
    11         //2.从IOC容器中获取Bean的实例
    12         ArithmeticCalculator arithmeticCalculator = ctx.getBean(ArithmeticCalculator.class);
    13         //3.使用bean
    14         int result = arithmeticCalculator.add(3, 6);
    15         System.out.println("result:" + result);
    16     }
    17 
    18 }

    运行结果:

     假如在Main.java代码最后再加入:

    1         result = arithmeticCalculator.div(12, 6);
    2         System.out.println("result:" + result);

    要使切面代码对该句也有效,需要在切面代码中把add改为*,否则不会有效,下图示:

    注:如果不改动代码仍为add,那就是表明只对add方法有效。

    【利用方法签名编写AspectJ切入点表达式】

    1.最典型的切入点表达式是根据方法的签名来匹配各种方法

    --execution * com.hk.spring.aop.impl.ArithmeticCalculator.*(..):匹配ArithmeticCalculator中声明的所有方法,第一个 “ * ” 代表任意修饰符以及任意返回值,第二个“ * ” 代表任意方法。“ .. ”匹配任意数量的参数。若目标类与接口与该切面在同一个包中,可以省略包名。

    --execution public* ArithmeticCalculator.*(..):匹配ArithmeticCalculator接口的所有公有方法。

    --execution public double ArithmeticCalculator.*(..):匹配ArithmeticCalculator中返回double类型数值的方法。

    --execution public double ArithmeticCalculator.*(double,..):匹配第一个参数为double类型的方法,“ .. ” 匹配任意数量任意类型的参数。

    --execution public double ArithmeticCalculator.*(double,double):匹配参数类型为 double,double 类型的方法。

    运行结果:

      

    【让通知访问当前连接点的细节】

    可以在通知方法中声明一个类型为JoinPoint的参数。然后就能访问链接细节。如方法名称和参数值。

    附:

    小结:

    1.Spring AOP

    (1)加入jar包:

    (2)在配置文件中加入AOP命名空间。

    (3)基于注解的方式

    ①在配置文件中加入如下配置:

    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

    ②把横切关注点的代码抽象到切面的类中。

    (i)切面首先是一个IOC中的Bean,即加入 @Component 注解

    (ii)切面还需要@Aspect 注解

    ③在类中声明各种通知:

    (i)声明一个方法

    (ii)在一个方法前加入@Before注解

    ④可以在通知方法中声明一个类型为JoinPoint的参数。然后就能访问链接细节。如方法名称和参数值。

     1 //把这个类声明为一个切面。步骤:需要把该类放入到IOC容器中,然后再声明为一个切面。
     2 @Aspect
     3 @Component
     4 public class LoggingAspect {
     5     //声明该方法是一个前置通知:在目标方法之前执行
     6     @Before("execution(public int com.hk.spring.aop.impl.ArithmeticCalculator.*(int,int))")
     7     public void beforeMethod(JoinPoint joinPoint){
     8         String methodName = joinPoint.getSignature().getName();
     9         List<Object> args = Arrays.asList(joinPoint.getArgs());
    10         System.out.println("The method " + methodName + " begins with " + args);
    11     }
    每接触一个新领域,我就像一块掉进水里的海绵,四面八方的养分都让我不断充实。O(∩_∩)O~
  • 相关阅读:
    Updates were rejected because the tip of your current branch is behind 问题出现解决方案
    git初始化本地项目及关联github远程库
    git项目提交后执行添加忽略操作
    HTML5基础总结
    图表Echarts的使用
    百度API使用--javascript api进行多点定位
    HtmlAgilityPach基本使用方法
    Redis可以做哪些事儿?
    Asp.Net将Session保存在数据库中
    css基础学习
  • 原文地址:https://www.cnblogs.com/zhzcode/p/9665046.html
Copyright © 2011-2022 走看看