springAOP中的各种通知

原创 2016年12月04日 22:59:01


  在上一篇博客中我们介绍了AOP的一些基本概念,并且在博客中的Demo我们没有使用配置文件的形式来实现,在博客的结尾我们我们也抛出了那样写的问题,在这篇博客中我们就用配置文件的方式来来介绍AOP中的五大通知。

 前置通知(before):在目标方法执行之前执行

 后置通知(after):在目标方执行完成后执行,如果目标方法异常,则后置通知不再执行

 异常通知(After-throwing):目标方法抛出异常的时候执行  

 最终通知(finally);不管目标方法是否有异常都会执行,相当于try。。catch。。finally中的finally

 环绕通知(round):可以控制目标方法是否执行

 下面就通过一个栗子来总结一下这几个通知应该如何使用.

           

  上面截图就是demo的基本目录结构,先来说一下jar包,其中aspectjrt.jar和aspectjweaver.jar是springAOP配置文件形式所需要的jar包,其实这和springAOP的由来有联系,因为AOP的思想最原始就是aspect技术,只不过当时开发人员不知道这个技术干什么用,导致该项技术没有什么用武之地,但是到后来spring的作者意识到这种思想的优势的使用,加以整合提出aop的思想,使这项技术到达了巅峰。cglib是代理对象形成的另一种形式。

  和上一篇博客对比我们可以发现,我们不需要自己写拦截器,而是在配置文件中实现。

  首先来看一下配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/aop 
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
      <!-- 
   	      导入目标类
   	      导入切面
   	      进行aop的配置
    -->        
   <bean id="personDao" class="com.itheima11.spring.aop.xml.transaction.PersonDaoImpl"></bean>
   <bean id="transaction" class="com.itheima11.spring.aop.xml.transaction.Transaction"></bean>
   
	<aop:config>
	<!-- 
   			切入点表达式
   			  符合切入点表达式的类要产生代理对象
   			  expression就是切入点表达式
   			  id 标示符
   		 -->
		<aop:pointcut 
			expression="execution(* com.itheima11.spring.aop.xml.transaction.PersonDaoImpl.*(..))" 
			id="perform"/>
		<aop:aspect ref="transaction">
			<!-- 
				前置通知
				    1、在目标方法执行之前
				    2、前置通知中,方法有一个参数JoinPoint
			 -->
			
			<aop:before method="beginTransaction" pointcut-ref="perform"/>
			
			<!-- 
				后置通知
				   1、在目标方法执行之后
				   2、能够获取目标方法的返回值
				       returning="val" val就是通知方法中 后置通知中的参数名称
				   3、如果目标方法产生异常,则后置通知不再执行
			 -->
			
			<aop:after-returning method="commit" pointcut-ref="perform" returning="val"/>
			
			<!-- 
				异常通知
				          获取目标方法抛出的异常信息
					throwing="ex"
			 -->
			<aop:after-throwing method="throwingMethod" pointcut-ref="perform" throwing="ex"/>
			<!-- 
				最终通知
			 -->
			<aop:after method="finallyMethod" pointcut-ref="perform"/>
			<!-- 
				环绕通知
				  	能够控制目标方法的执行
				  	环绕通知可以有返回值,这个返回值就是代理对象的方法的返回值
				  	前置通知和后置通知只能在目标方法执行之前和之后加代码,但是不能控制目标方法的执行
			 -->
			<aop:around method="aroundMethod" pointcut-ref="perform"/>
		</aop:aspect>
	</aop:config>
</beans>

  核心类切面代码:

package com.itheima11.spring.aop.xml.transaction;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class Transaction {
	/**
	 * 前置通知 参数:JoinPoint 连接点:客户端调用哪个方法,这个方法就是连接点
	 */
	public void beginTransaction(JoinPoint joinPoint) {
		System.out.println("目标类:" + joinPoint.getTarget().getClass());
		System.out.println("目标方法的名称:" + joinPoint.getSignature().getName());
		System.out.println("目标方法的参数:" + joinPoint.getArgs().length);
		System.out.println("begin transaction");
	}

	/**
	 * 后置通知 val接收目标类的目标方法的返回值
	 */
	public void commit(JoinPoint joinPoint, Object val) {
		System.out.println("返回值:" + val);
		System.out.println("commit");
	}

	/**
	 * 异常通知 不管是否目标方法是否抛出异常,都会执行这个方法,相当于finally
	 */
	public void throwingMethod(JoinPoint joinPoint, Throwable ex) {
		System.out.println(ex.getMessage());
	}

	/**
	 * 最终通知
	 */
	public void finallyMethod() {
		System.out.println("finally method");
	}

	/**
	 * 环绕通知 可以控制目标方法的是否执行
	 */
	public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
		System.out.println("around method");
		return joinPoint.proceed();// 执行目标方法,如果不写行代码 则目标方法不会执行
	}
}
  客户端代码

package com.itheima11.spring.aop.xml.transaction;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


/**
 * aop的原理
 *     1、启动spring容器
 *     2、spring容器会为personDao和transaction实例化
 *     3、spring容器解析aop:config的配置
 *         当spring容器解析到切入点表达式的时候,就会把切入点表达式解析出来
 *            会让切入点表达式的类和spring容器中的类进行匹配
 *               如果匹配成功,则会为该对象创建代理对象
 *                  代理对象的方法形成=通知+目标方法
 *               如果匹配不成功,则会报错
 *     4、在客户端context.getBean时,如果当前的对象有代理对象,则返回代理对象
 *              如果没有代理对象返回对象的本身
 *     5、在spring内部会检查目标类有没有实现接口
 *           如果目标类实现了接口,则采用jdkproxy产生代理对象
 *           如果目标类没有实现接口,则采用cglibproxy产生代理对象
 * @author zd
 *
 */
public class PersonDaoTest {
	@Test
	public void testSpring(){
		ApplicationContext context = 
				new ClassPathXmlApplicationContext("applicationContext.xml");
		PersonDao personDao = (PersonDao)context.getBean("personDao");
		String s = personDao.savePerson();
		System.out.println(s);
	}
}
  结果:

  

  小编在都将重要的注释写在代码中,请读者自行体会。上面这个demo就是对于springAOP中常用的几个通知的实现,在实际的场景我们需要不同的需求来运用不同的通知来实现。

  当我们对这个模式比较熟悉以后,里面比较重要是我们切入点表达式的编写,我们不在用原先的if。。else。。来实现,我们根据需求编写表达式实现。所以我们需要熟悉表达式的编写。

  在下面的博客中将会利用这些基本知识,实现具体的业务需求。


  

   

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

spring(AOP) 各种通知概念

通知概念前置通知 1. 在目标方法执行之前执行。后置通知 1. 在目标方法执行之后执行 2. 可以获取目标方法的返回值 3. 当目标方法遇到异常,不执行最终通知 1. 无论目标方法...

spring知识六------AOP五大通知

AOP通知 重用切面 切入点表达式 切面优先级 xml配置通知

Spring aop 前置通知、后置通知、返回通知、 异常通知 、后置通知

Spring AOP定义切面 Ⅰ 首先介绍一下写Spring Aop思路  一、首先在项目中加入aop所需要的jar aopalliance-1.0.jar aspectjweaver-1.6.11...

spring aop的五种通知类型

spring aop通知(advice)分成五类: 前置通知、正常返回通知、异常返回通知、返回通知、环绕通知...
  • cqabl
  • cqabl
  • 2015年07月20日 10:41
  • 13671

spring aop的五种通知类型

spring aop通知(advice)分成五类: 前置通知、正常返回通知、异常返回通知、返回通知、环绕通知...
  • cqabl
  • cqabl
  • 2015年07月20日 10:41
  • 13671

【Lucene】Apache Lucene全文检索引擎架构之搜索功能

上一节主要总结了一下Lucene是如何构建索引的,这一节简单总结一下Lucene中的搜索功能。主要分为几个部分,对特定项的搜索;查询表达式QueryParser的使用;指定数字范围内搜索;指定字符串开...
  • eson_15
  • eson_15
  • 2016年07月11日 18:08
  • 10337

SpringAop xml方式配置通知

  • 2016年11月25日 18:02
  • 11KB
  • 下载

SpringAOP环绕通知的使用

上一篇文章介绍了SpringAOP的概念以及简单使用:SpringAOP概念及其使用在springAOP中有五种通知,环绕通知是最为强大的通知。它能够让你编写的逻辑将被通知的目标方法完全包装起来。实际...
  • wqh8522
  • wqh8522
  • 2017年06月07日 16:23
  • 401

SpringAOP处理通知中的参数

Spring借助AspectJ的切点表达式语言来定义Spring切面在spring中尝试使用其他指示器时,会抛出IllegalArgument-Exception异常。如上的这些指示器,只有excep...
  • wqh8522
  • wqh8522
  • 2017年06月08日 09:35
  • 164

SpringAOP 通知(adivce)- methodIntercepor

环绕通知(即methodIntercepor) 是SpringAOP 通知模块中的一种通知方式。可用在指定方法执行之前,执行之后。对于同时要实现两种通知的方法是一种便利。若使用BeforeAdivce...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:springAOP中的各种通知
举报原因:
原因补充:

(最多只允许输入30个字)