当前位置: 首页 > news >正文

Spring AOP 1

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

Spring除了支持Schema方式配置AOP,还支持注解方式:使用@AspectJ风格的切面声明。

启用对@AspectJ的支持

<aop:aspectj-autoproxy/> 

声明切面

@AspectJ风格的声明切面只需要使用@Aspect注解进行声明,可以在该切面中进行切入点及通知定义

@Aspect()  

Public class Aspect{ ....}

将此切面声明成Bean,<bean id="aspect" class="……Aspect"/>  

声明切入点

@AspectJ风格的命名切入点使用org.aspectj.lang.annotation包下的@Pointcut+方法(方法必须是返回void类型)实现。

@Pointcut(value="切入点表达式", argNames = "参数名列表")  

public void pointcutName(……) {}

argNames指定命名切入点方法参数列表参数名字,可以有多个用“,”分隔,这些参数将传递给通知方法同名的参数,同时比如切入点表达式“args(param)”将匹配参数类型为命名切入点方法同名参数指定的参数类型。

pointcutName切入点名字,可以使用该名字进行引用该切入点表达式。

@Pointcut(value="execution(* cn.javass..*.sayAdvisorBefore(..)) && args(param)", argNames = "param")  

public void beforePointcut(String param) {}  

定义了一个切入点,名字为“beforePointcut”,该切入点将匹配目标方法的第一个参数类型为通知方法实现中参数名为“param”的参数类型。

声明通知

5种通知类型:前置通知,后置返回通知,后置异常通知,后置最终通知,环绕通知。

前置通知:@Before(value = "切入点表达式或命名切入点", argNames = "参数列表参数名") 

1、定义接口和实现,在此我们就使用Schema风格时的定义;

2、定义切面:

import org.aspectj.lang.annotation.Aspect;

@Aspect 

public class HelloWorldAspect2 {  }

3、定义切入点:

@Pointcut(value="execution(* cn.javass..*.sayAdvisorBefore(..)) && args(param)", argNames = "param")

public void beforePointcut(String param) {} 

4、定义通知:

@Before(value = "beforePointcut(param)", argNames = "param") 

public void beforeAdvice(String param) {System.out.println("====before advice param:" + param);}

5、xml配置

<?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/beans  

           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  

           http://www.springframework.org/schema/aop  

           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">             

  <aop:aspectj-autoproxy/>  

  <bean id="helloWorldService" class="cn.javass.spring.chapter6.service.impl.HelloWorldService"/>     <bean id="aspect"  class="cn.javass.spring.chapter6.aop.HelloWorldAspect2"/>  

</beans>  

总结:

切面、切入点、通知全部使用注解完成:

       1)使用@Aspect将POJO声明为切面;

       2)使用@Pointcut进行命名切入点声明,同时指定目标方法第一个参数类型必须是java.lang.String,对于其他匹配的方法但参数类型不一致的将也是不匹配的,通过argNames = "param"指定了将把该匹配的目标方法参数传递给通知同名的参数上;

       3)使用@Before进行前置通知声明,其中value用于定义切入点表达式或引用命名切入点;

       4)配置文件需要使用<aop:aspectj-autoproxy/>来开启注解风格的@AspectJ支持;

       5)需要将切面注册为Bean,如“aspect”Bean;

       6)测试代码完全一样。

后置返回通知:

@AfterReturning(  

    value="切入点表达式或命名切入点",  

    pointcut="切入点表达式或命名切入点",  

    argNames="参数列表参数名",  

    returning="返回值对应参数名")  

@AfterReturning(  

    value="execution(* cn.javass..*.sayBefore(..))",  

    pointcut="execution(* cn.javass..*.sayAfterReturning(..))",  

    argNames="retVal", returning="retVal")  

public void afterReturningAdvice(Object retVal) {  

    System.out.println("=====after returning advice retVal:" + retVal);  

}  

其它代码与前置通知一样。

后置异常通知:

@AfterThrowing (  

    value="切入点表达式或命名切入点",  

    pointcut="切入点表达式或命名切入点",  

    argNames="参数列表参数名",  

    throwing="异常对应参数名")  

@AfterThrowing(  

    value="execution(* cn.javass..*.sayAfterThrowing(..))",  

    argNames="exception", throwing="exception")  

public void afterThrowingAdvice(Exception exception) {  

    System.out.println("====after throwing advice exception:" + exception);  

}  

后置最终通知:

@After (  

    value="切入点表达式或命名切入点",  

    argNames="参数列表参数名")  

@After(value="execution(* cn.javass..*.sayAfterFinally(..))")  

public void afterFinallyAdvice() {  

    System.out.println("====after finally advice");  

}  

环绕通知:

@Around (  

    value="切入点表达式或命名切入点",  

    argNames="参数列表参数名") 

@Around(value="execution(* cn.javass..*.sayAround(..))")  

public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {  

    System.out.println("===around before advice");  

    Object retVal = pjp.proceed(new Object[] {"replace"});  

    System.out.println("===around after advice");  

    return retVal;  

}  

 

转载于:https://my.oschina.net/u/3705388/blog/1571618

相关文章:

  • 如何启动Nunit的调试功能
  • ELK日志分析系统实战(一)安装和部署
  • H3C路由器登录管理
  • Laravel5.1 条件性验证
  • Redhat7 增加swap分区
  • 进程调度器--UNIX还是是老大
  • 监控apache脚本原理
  • JAVA与.NET的相互调用——利用JNBridge桥接模式实现远程通讯
  • 13.liunx机器互相登录
  • nginx配置虚拟主机
  • mysql日志文件在哪
  • 21天让你成为Horizon View高手—Day7:配置View Connection Server
  • c用libcurl库实现https下get/post网络通信
  • bootstrap标题效果
  • nmap的用法
  • AWS实战 - 利用IAM对S3做访问控制
  • css系列之关于字体的事
  • css属性的继承、初识值、计算值、当前值、应用值
  • ERLANG 网工修炼笔记 ---- UDP
  • Laravel Mix运行时关于es2015报错解决方案
  • MySQL QA
  • PermissionScope Swift4 兼容问题
  • Spring Boot MyBatis配置多种数据库
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • Vue2.x学习三:事件处理生命周期钩子
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 马上搞懂 GeoJSON
  • 码农张的Bug人生 - 初来乍到
  • 时间复杂度与空间复杂度分析
  • 使用 Docker 部署 Spring Boot项目
  • 物联网链路协议
  • 学习ES6 变量的解构赋值
  • 阿里云服务器购买完整流程
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • ​马来语翻译中文去哪比较好?
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • !!Dom4j 学习笔记
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • ()、[]、{}、(())、[[]]等各种括号的使用
  • (ZT)薛涌:谈贫说富
  • (搬运以学习)flask 上下文的实现
  • (附源码)springboot“微印象”在线打印预约系统 毕业设计 061642
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (考研湖科大教书匠计算机网络)第一章概述-第五节1:计算机网络体系结构之分层思想和举例
  • (译) 理解 Elixir 中的宏 Macro, 第四部分:深入化
  • (原創) 未来三学期想要修的课 (日記)
  • (转)socket Aio demo
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • ***详解账号泄露:全球约1亿用户已泄露
  • .net core Swagger 过滤部分Api
  • .net core webapi Startup 注入ConfigurePrimaryHttpMessageHandler
  • .NET MVC、 WebAPI、 WebService【ws】、NVVM、WCF、Remoting
  • .NET 分布式技术比较