1.1           Spring的AOP配置文件和注解实例解析

AOP它利用一种称为"横切"的技术,将那些与核心业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。例如打印日志。与核心业务逻辑无关,但是却贯穿整个程序当中。所以使用AOP切面技术将日志和核心业务逻辑分离开来,通过配置文件或者注解配置切面,并为切面设置过滤条件,过滤条件是程序中的方法,表示调用程序中的这些方法时会调用日志切面的方法来打印日志,相当于是一种过滤符合条件就触发打印日志的机制。而不是将日志和程序中的方法写在一起。

1.1.1            AOP配置文件方式

通过配置文件设置切面,切入点,设置与切入点关联的触发方法,配置核心业务函数与触发函数之间的映射关系。一旦触发方法调用,就会进入切面,在触发方法前、后、异常等情况下执行相关函数。

(1)为日志类LogAop配置切面信息,配置applicationContext.xml 中logAopBean是配置日志的bean,提供给IOC调用。aop:aspect id="logAspect"则是定义一个切面。

<!-- 配置日志类logAopBean为bean ,提供给IOC使用-->

<bean id="logAopBean" class="com.demo.common.aop.LogAop"></bean>

<aop:config>

<!—设置切面,logAopBean是日志类的名称 -->

<aop:aspect id="logAspect" ref="logAopBean">

<!—设置切入点, expression指定过滤条件,表示com.demo 内部的所有方法,id指定切入的方法,这个方法是一个空函数,只是用于后面关联日志类中要调用的其他方法-->

<aop:pointcut expression="execution(* com.demo..*(..))" id="allMethod"/>

<!—com.demo中的方法,在调用时,就会触发日志类中的函数,下面四个方法分别是调用前打日志,调用异常打日志,调用返回打日志,调用结束打日志,切入点allMethod和核心业务类中的方法关联,日志类中的方法和切入点方法关联。核心方法调用时,触发切入点,切入点根据方法的执行情况去执行对应的日志方法。 -->

<aop:before method="before" pointcut-ref="allMethod" />

<aop:after-throwing method="afterThrowing" pointcut-ref="allMethod" />

<aop:after-returning method="afterReturn" pointcut-ref="allMethod" />

<aop:after method="after" pointcut-ref="allMethod" />

</aop:aspect>

</aop:config>

(2)定义日志类,实现日志类中前置、后置、异常、返回等方法。

package com.demo.common.aop;

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.ProceedingJoinPoint;

public class LogAop {

public void before(JoinPoint call){

String className = call.getTarget().getClass().getName();

String methodName = call.getSignature().getName();

System.out.println("开始执行:"+className+"."+methodName+"()方法...");

}

public void afterThrowing(JoinPoint call){

String className = call.getTarget().getClass().getName();

String methodName = call.getSignature().getName();

System.out.println(className+"."+methodName+"()方法抛出了异常...");

}

public void afterReturn(JoinPoint call){

String className = call.getTarget().getClass().getName();

String methodName = call.getSignature().getName();

System.out.println(className+"."+methodName+"()方法正常执行结束...");

}

public void after(JoinPoint call){

String className = call.getTarget().getClass().getName();

String methodName = call.getSignature().getName();

System.out.println(className+"."+methodName+"()最终执行步骤(finally)...");

}

/*//用来做环绕通知的方法可以第一个参数定义为org.aspectj.lang.ProceedingJoinPoint类型

public Object doAround(ProceedingJoinPoint call) throws Throwable {

Object result = null;

this.before(call);//相当于前置通知

try {

result = call.proceed();

this.afterReturn(call); //相当于后置通知

} catch (Throwable e) {

this.afterThrowing(call); //相当于异常抛出后通知

throw e;

}finally{

this.after(call);  //相当于最终通知

}

return result;

}*/

}

1.1.2            AOP注解方式

使用注解去代替配置文件,告诉IOC容器,切面、切入点、触发函数和核心业务方法之间的映射关系。前置方法、后置方法、异常方法、正常返回方法。

在配置文件中声明LogAnnotationAspect为logAspectBean,告诉IOC容器这是一个bean。

<bean id="logAspectBean" class="com.demo.common.aop.LogAnnotationAspect"></bean>

<aop:aspectj-autoproxy/>

package com.demo.common.aop;

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.After;

import org.aspectj.lang.annotation.AfterReturning;

import org.aspectj.lang.annotation.AfterThrowing;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.aspectj.lang.annotation.Pointcut;

@Aspect  //定义切面类

public class LogAnnotationAspect {

@SuppressWarnings("unused")

//定义切入点,提供一个方法,这个方法的名字就是切入点的id

@Pointcut("execution(* com.demo..*(..))")  //关联核心业务函数

private void allMethod(){}

//针对指定的切入点表达式选择的切入点应用前置通知

@Before("allMethod()")

public void before(JoinPoint call) {

String className = call.getTarget().getClass().getName();

String methodName = call.getSignature().getName();

System.out.println("开始执行:"+className+"."+methodName+"()方法...");

}

//访问命名切入点来应用后置通知

@AfterReturning("allMethod()")

public void afterReturn(JoinPoint call) {

String className = call.getTarget().getClass().getName();

String methodName = call.getSignature().getName();

System.out.println(className+"."+methodName+"()方法正常执行结束...");

}

//应用最终通知

@After("allMethod()")

public void after(JoinPoint call) {

String className = call.getTarget().getClass().getName();

String methodName = call.getSignature().getName();

System.out.println(className+"."+methodName+"()最终执行步骤(finally)...");

}

//应用异常抛出后通知

@AfterThrowing("allMethod()")

public void afterThrowing(JoinPoint call) {

String className = call.getTarget().getClass().getName();

String methodName = call.getSignature().getName();

System.out.println(className+"."+methodName+"()方法抛出了异常...");

}

//应用周围通知

//@Around("allMethod()")

public Object doAround(ProceedingJoinPoint call) throws Throwable{

Object result = null;

this.before(call);//相当于前置通知

try {

result = call.proceed();

this.afterReturn(call); //相当于后置通知

} catch (Throwable e) {

this.afterThrowing(call);  //相当于异常抛出后通知

throw e;

}finally{

this.after(call);  //相当于最终通知

}

return result;

}

}

Spring的AOP配置文件和注解实例解析的更多相关文章

  1. spring 学习(二):spring bean 管理--配置文件和注解混合使用

    spring 学习(二)spring bean 管理--配置文件和注解混合使用 相似的,创建 maven 工程,配置pom.xml 文件,具体可以参考上一篇博文: sprint 学习(一) 然后我们在 ...

  2. Spring 中基于 AOP 的 @AspectJ注解实例

    @AspectJ 作为通过 Java 5 注释注释的普通的 Java 类,它指的是声明 aspects 的一种风格.通过在你的基于架构的 XML 配置文件中包含以下元素,@AspectJ 支持是可用的 ...

  3. spring Quartz基于配置文件和注解的实现

    这里仅仅是做简单的记录怎样实现. 一.基于配置文件的实现 ①编写须要调度的类 package com.study; import org.springframework.scheduling.anno ...

  4. Spring框架 aop操作的注解方法 基于aspectj的自动注解aop方法 抽取相同的value="execution(public void cn.itcast.f_aspect.CRUD.*())"

    首先是在xml配置文件中配置好对象,然后开启aop的注解方法——即<aop:aspectj-autoproxy></aop:aspectj-autoproxy> xml代码如下 ...

  5. 黑马Spring学习 AOP XML和注解配置 5种通知 切点切面通知织入

    业务类 package cn.itcast.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoin ...

  6. spring中少用的注解@primary解析

    这次看下spring中少见的注解@primary注解,例子 @Component public class MetalSinger implements Singer{ @Override publi ...

  7. 【spring boot】配置文件 application.properties 属性解析

    1.JPA  hibernate命名策略 完整命名策略 ,查看:http://www.cnblogs.com/sxdcgaq8080/p/7910474.html 2.hibernate的DDL执行策 ...

  8. Spring的AOP基于AspectJ的注解方式开发3

    上上偏博客介绍了@Aspect,@Before 上篇博客介绍了spring的AOP开发的注解通知类型:@Before,@AfterThrowing,@After,@AfterReturning,@Ar ...

  9. 框架源码系列十:Spring AOP(AOP的核心概念回顾、Spring中AOP的用法、Spring AOP 源码学习)

    一.AOP的核心概念回顾 https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#a ...

随机推荐

  1. nGrinder Maven工程使用

    1:新建Maven groovy工程 2:SVN Checkout Maven工程 3:新建JUnit脚本,并运行,提示报错 java.lang.RuntimeException: Please ad ...

  2. android之进度条

    xml引用 <ProgressBar android:id="@+id/pb_progressbar" style="@style/StyleProgressBar ...

  3. python简说(十三)递归

    #递归就是函数自己调用自己count = 0# def abc():# pass# abc()最多循环999次

  4. 识别简单的答题卡(Bubble sheet multiple choice scanner and test grader using OMR, Python and OpenCV——jsxyhelu重新整编)

    该博客转自www.pyimagesearch.com,进行了相关修改补充. Over the past few months I've gotten quite the number of reque ...

  5. CentOS 7 install slurm cluster

    //slurm install //CentOS 7 system //192.168.159.141 node01 //192.168.159.142 node02 systemctl stop f ...

  6. 【Python57--正则1】

    一.正则表达式匹配IP地址 1.search()方法:用于在字符串中搜索正则表达式模式第一次出现的位置 >>> import re >>> re.search(r' ...

  7. ChromeDriver与Chrome版本对应关系

    备注: 下载ChromeDriver的时候,可以在notes.txt文件中查看版本对应关系. ----------ChromeDriver v2.29 (2017-04-04)---------- S ...

  8. Python3 tkinter基础 Checkbutton anchor for生成多个控件并西对齐

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  9. (zhuan) Attention in Long Short-Term Memory Recurrent Neural Networks

    Attention in Long Short-Term Memory Recurrent Neural Networks by Jason Brownlee on June 30, 2017 in  ...

  10. Microsoft.EntityFrameworkCore.Sqlite的学习

    SQLite in ASP.NET Core with EntityFrameworkCore ASP.NET Core 2: Using SQLite as a light weight datab ...