AOP之5种增强方法应用范例

2023-11-13

  林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka

         Spring AOP 提供了 5 种类型的通知,它们分别是 Before Advice(前置通知)、After Returning Advice(后置通知)、Interception Around Advice(周围通知)、Throws Advice(异常通知)和 Introduction Advice(引介通知)。下面分别进行介绍。

本文工程免费下载

1、前置通知(前置增强)

       前置通知顾名思意,该通知织入在方法调用之前。我们可以通过Spring 的MethodBeforeAdvice 接口实现。MethodBeforeAdvice 只提供方法before(),该方法无返回值,方法接受调用方法,方法参数和目标对象这3个参数。这里需要注意的是,虽然before()方法得到了调用方法的参数,这里值得注意的是方法参数可以进行更改!

创建一个工人接口类:

/**  
*功能 工人接口类
*作者 林炳文(ling20081005@126.com 博客:http://blog.csdn.net/evankaka)  
*时间 2015.4.22 
*/
package com.mucfc.advice;
public interface Worker {
	void getTool(String tool);
	void digSomething(String type);
	void initWork();

}

工人实现类:

/**  
*功能 工人实现类
*作者 林炳文(ling20081005@126.com 博客:http://blog.csdn.net/evankaka)  
*时间 2015.4.22 
*/
package com.mucfc.advice;

import javax.management.RuntimeErrorException;

public class DigWorker implements Worker{

	@Override
	public void getTool(String tool) {
     System.out.println("---------------调用方法--------------");	
     System.out.println("领取工具:"+tool);	
    // throw new RuntimeException("运行异常");
	}

	@Override
	public void digSomething(String type) {
	     System.out.println("---------------调用方法--------------");	
		 System.out.println("开始卖力挖取:"+type);	
		
	}

	@Override
	public void initWork() {
		System.out.println("生成一个DigWorker实例");			
	}
	

}

3、创建前置增强的方法:

/**  
*功能 前置增强方法
*作者 林炳文(ling20081005@126.com 博客:http://blog.csdn.net/evankaka)  
*时间 2015.4.22 
*/
package com.mucfc.advice;
import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;
public class WearingBeforeAdvice implements MethodBeforeAdvice{


	public void before(Method arg0, Object[] arg1, Object arg2)
			throws Throwable {
		String thing=(String)arg1[0];
		System.out.println("--------------进行前置增强---------------");
		System.out.println("得到"+thing+"之前先穿上工作服!!");
	}

}

4、将增强方法织入到相应的地方
    //1、不使用xml配置实例化
    Worker target=new DigWorker();    
    BeforeAdvice advice=new WearingBeforeAdvice();
    //Spring提供的代理工厂
    ProxyFactory pFactory=new ProxyFactory();
    //设置代理目标,默认使用Cglib动态代理
    pFactory.setTarget(target);
    
    //为代理目标添加前置增强,这里会为目标的每个方法都增加增强
    pFactory.addAdvice(advice);
    //生成代理实例
    Worker proxy=(Worker)pFactory.getProxy();
    proxy.getTool("钻机");
    proxy.digSomething("煤炭");

结果:在工人实现类的两个方法调用之前都进行了前置增强


接口代理默认是使用JDK动态代理,如要使用CGLIB动态代码,在加上:

    //指定做优化,又将使用cglib动态
    pFactory.setOptimize(true);

若要使用JDK动态代理,加上:

    //指定对接口进行代理,通过JDK动态代理
    pFactory.setInterfaces(target.getClass().getInterfaces());
二、后置增强

后置通知(After returning advice):在某连接点正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。

1、增强方法代理

/**  
*功能 后置增强方法
*作者 林炳文(ling20081005@126.com 博客:http://blog.csdn.net/evankaka)  
*时间 2015.4.22 
*/
package com.mucfc.advice;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class WeaningAfterAdvice implements AfterReturningAdvice{

	@Override
	public void afterReturning(Object arg0, Method arg1, Object[] arg2,
			Object arg3) throws Throwable {
		System.out.println("--------------进行后置增强---------------");
		System.out.println("工作结束,请先脱掉工作服");
	}

}
工人还是上面的工人,其它方法不变。

2、我们在进行增强配置时,可以直接使用API函数,但是这样比较复杂,下面我们来用XML注解配置的方法来同时实现前置和后后置增强

在src文件夹下新建 一个XML文件,取名为beans.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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans  
                http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
        http://www.springframework.org/schema/context  
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

然后就是下面的配置如下:

        <!-- 要进行增强的目标 -->
	<bean id="target" class="com.mucfc.advice.DigWorker" init-method="initWork"/>    
        
	<!-- 前置增强的方法 -->
	<bean id="beforeAdvice" class="com.mucfc.advice.WearingBeforeAdvice" />
	<!-- 后置增强的方法 -->
	<bean id="afterAdvice" class="com.mucfc.advice.WeaningAfterAdvice" />
	
	<!--同时设置前置增强和后置增强方法  -->
	<bean id="worker1" class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="com.mucfc.advice.Worker" p:interceptorNames="beforeAdvice,afterAdvice"
		p:target-ref="target" lazy-init="true"/>
这里 p:interceptorNames="beforeAdvice,afterAdvice"表示同时加入了前置和后置增强。

lazy-init="true"表示能要用的时候才初始化这个实例

3、调用

   //2、下面使用Spring的xml配置实例化
   ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
   //worker1带前置和后置增强
   Worker worker1=(Worker)ctx.getBean("worker1");
   System.out.println("worker1进入工作:");
   worker1.getTool("锄头");
结果如下:


在调用方法之前都进行了前置和后置增强,注意,这里会为工人类的所有方法都织入增强!


三、环绕增强

环绕通知(Around Advice):包围一个连接点的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它自己的返回值或抛出异常来结束执行。


1、添加增强方法类:

/**  
*功能 环绕增强方法
*作者 林炳文(ling20081005@126.com 博客:http://blog.csdn.net/evankaka)  
*时间 2015.4.22 
*/
package com.mucfc.advice;
import java.lang.reflect.Method;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;;
public  class WearingInterceptor implements MethodInterceptor{

	@Override
	public Object invoke(MethodInvocation arg0) throws Throwable {
		Object[] args=arg0.getArguments();//目标方法入参
		String toolname=(String)args[0];
		System.out.println("--------------环绕增强开始---------------");
		System.out.println("得到"+toolname+"之前先穿上工作服");
		Object object=arg0.proceed();
		System.out.println("工作结束,请先脱掉工作服");
		System.out.println("--------------环绕增强结束---------------");
;				return object;
	}


}
2、然后还是在beans.xml中配置:

        <!-- 环绕增强的方法 -->
	<bean id="aroundAdvice" class="com.mucfc.advice.WearingInterceptor" />	
	<!--设置环绕增强方法  -->
	<bean id="worker2" class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="com.mucfc.advice.Worker" p:interceptorNames="aroundAdvice"
		p:target-ref="target" lazy-init="true"/>

3、使用

   //work2带环绕增强
   Worker worker2=(Worker)ctx.getBean("worker2");
   System.out.println("worker2进入工作:");
   worker2.getTool("钻机");

结果:

三、异常抛出增强

异常通知(After throwing advice):在方法抛出异常退出时执行的通知。

1、将前置增强方法中的工人实现 类的方法增个, throw new RuntimeException("运行异常");

	@Override
	public void getTool(String tool) {
     System.out.println("---------------调用方法--------------");	
     System.out.println("领取工具:"+tool);	
     throw new RuntimeException("运行异常");
	}

2、处理异常抛出的类

/**  
*功能 异常抛出增强类
*作者 林炳文(ling20081005@126.com 博客:http://blog.csdn.net/evankaka)  
*时间 2015.4.22 
*/
package com.mucfc.advice;
import java.lang.reflect.Method;

import org.springframework.aop.ThrowsAdvice;

public class WeaningThrowAdvice implements ThrowsAdvice {
	public void afterThrowing(Method method, Object[] args, Object target,
			Exception ex) throws Throwable {
    System.out.println("--------------------");
    System.out.println("method:"+method.getName());
    System.out.println("抛出异常"+ex.getMessage());
    System.out.println("成功回滚事务");
	}

}

3、XML配置

	<!-- 异常抛出增强的方法  -->
	<bean id="thorwAdvice" class="com.mucfc.advice.WeaningThrowAdvice" />
		
	<!--设置异常抛出增强方法  proxyTargetClass="true",使用CgLib代理-->
		<bean id="worker3" class="org.springframework.aop.framework.ProxyFactoryBean"
		p:interceptorNames="thorwAdvice"
		p:target-ref="target" 
		p:proxyTargetClass="true"/>

4、使用

   //work3带环绕增强
  Worker worker3=(Worker)ctx.getBean("worker3");
   System.out.println("worker3进入工作:");
   worker3.getTool("锤子");

注意,由于这里给方法强制抛出了异常,所以要运行上面的代码,记得要把前面的增强方法测试的代码都给去掉,只留下以下代码:

五、引介增强

引介增强是一种比较特殊的增强类型,它不是在目标方法周围织入增强,而是为目标类创建新的方法和属性,所以引介增强的连接点是类级别的,而非方法级别的。通过引介增强,我们可以为目标类添加一个接口的实现,即原来目标类未实现某个接口,通过引介增强可以为目标类创建实现该接口的代理。一般用得比较 少,这里就不写代码了

本文工程免费下载

林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

AOP之5种增强方法应用范例 的相关文章

随机推荐

  • UVA 1601 The Morning after Halloween [DBFS]

    The Morning after Halloween Time Limit 12000MS 64bit IO Format lld llu 直接搜索时间过不了 可以先把底图抽出来 这样的话就不用O maxn maxn 5 来判断是否可以转
  • qemu模拟器搭建arm运行环境搭建笔记

    qemu system arm M vexpress a9 m 512M kernel home lyk Downloads qemu linux 3 16 arch arm boot zImage nographic append roo
  • SD2.0软件大会纪实 - 个人观感

    12月9日 10日 SD2 0大会在上海光大会展中心国际大酒店举行 有幸参加这场盛会 将这两天的所得分享一下 以下文字是通过回忆并参考了CSDN网站的报道整理出来的 9日是全体大会 上午Keynote基本上是个广告的集合 CSDN给自己的各
  • 算法导论随笔(十五):线性规划与单纯形算法(上篇:基本概念)

    线性规划 Linear Programming 问题指的是在给定有限资源的前提下 最大化或最小化某个目标的问题 这里我将分上下两篇来谈谈线性规划和单纯形算法 前言 线性规划问题有很多例子 比如在算法导论随笔 六 贪心算法Greedy alg
  • MSRA实习记

    文章目录 前言 时间线 实习生集体 办公楼 工作环境 饮食 娱乐活动 薪酬待遇 住宿 总结 前言 我是哈工大2018级本科生 由于大三课程枯燥 选择到北京实习 偶然看到了诗昭姐的招聘启事 幸运地获得了她的认可 获得了人生第一份实习 加入了D
  • Excel分割字符串

    在数据处理中我们经常会遇到分割字符的情况 比如读取csv文件 Excel提供了可视化的字符串分割方法 1 按分隔符 分割字符串 2 选择用 逗号 分割 3 结果如图
  • 自动化运维---ansible常用模块之文件操作(file&blockinfile&lineinfile模块)

    自动化运维 ansible常用模块之文件操作 file blockinfile lineinfile模块 文章目录 自动化运维 ansible常用模块之文件操作 file blockinfile lineinfile模块 1 file模块
  • 7. QML类中对象树的创建和销毁顺序是这样的

    简述 有下面一段代码 通常会有需求在Component onCompleted信号之后做一些初始化操作 那这些组件初始化完成的顺序是怎样的 同时有创建完成的信号 也有对应销毁完成的信号 类似C 中的构造和析构函数 但我们这里叫信号处理程序
  • java三种分页查询的方式

    第一种 分页 需要查询出总数 第二种分页如果是以id为主键并且是递增的情况 第三种直接用do while进行分页查询 不需要查询总个数和最大最小值 mybatis plus分页 第四种分页 for循环分页
  • Vue指令学习

    目录 v text 设置标签的内容 v html 设置元素的innerHTML v on 为元素绑定事件 v show 根据布尔值控制元素的样式为显示或隐藏 v if 根据布尔值控制dom为显示或隐藏 v bind 在vue中为元素绑定属性
  • SQLite 如何在Windows下编译?

    SQLite 如何在Windows下编译 发表时间 2007 6 13 12 44 00 评论 打印 字体 大 中 小 本文链接 http blog pfan cn lounger 26745 html 复制链接 分享到 0 标签 C C
  • 计算机中¥符号按哪个键,电脑键盘符号快捷键大全 电脑键盘上每个键的作用?...

    电脑键盘符号快捷键大全 电脑键盘符号怎么打 很多朋友还不太清楚电脑的各个符号要怎么打 快捷键是什么呢 那么下面就一起来看看电脑键盘符号大全吧 电脑键盘符号怎么打 电脑键盘符号大全 常见的标点符号 分号 书名号 双引号 单引号 破折号 竖线
  • sublime简用

    1 使用goto anything 快速查询各种文件 可以快速定位CSS中选择器 或JavaScript中的function 2 其中的输入时选取简化的输入则可 bgc就代表background color 3 多行游标 光标放在单词中 然
  • hashmap为什么8转成红黑树_深入分析HashMap的红黑树实现方式

    在分析jdk1 8的HashMap实现原理之前 咱们先可以了解一下红黑树的设计 相比jdk1 7的HashMap而言 jdk1 8最重要的就是引入了红黑树的设计 当冲突的链表长度超过8个的时候 链表结构就会转为红黑树结构 01 故事的起因
  • Mysql——压缩包方式安装教程

    一 Mysql压缩包下载方式 zip版 5 7及8 0 的下载需到官方网站下载 不同版本对应能安装在不同的操作系统下 本次介绍的是mysql 8 0 30 winx64在win10下的安装方式 下载网址 MySQL Download MyS
  • android模拟器与宿主机通讯

    android模拟器与PC的端口映射 一 概述 Android系统为实现通信将PC电脑IP设置为10 0 2 2 自身设置为127 0 0 1 而PC并没有为Android模拟器系统指定IP 所以PC电脑不能通过IP来直接访问Android
  • Mysql增强半同步模式_MySQL增强半同步的搭建实验,和一些参数的个人理解

    环境信息 role ip port hostname master 192 168 188 101 4306 mysqlvm1 slave 192 168 188 201 4306 mysqlvm1 1 5306 6306 7306 MyS
  • eclipse搜索类快捷键

    习惯的编辑器可以提高编程效率 熟悉的快捷键可以提高工作效率 本文更新eclipse中常用的搜索快捷键 打开资源快捷键 Ctrl Shift R 通过在搜索框中输入名字可以很方便的在项目或工作空间中找某个文件 支持模糊查询功能 例如输入文件的
  • Linux防火墙

    关于linux系统防火墙 centos5 centos6 redhat6系统自带的是iptables防火墙 centos7 redhat7自带firewall防火墙 ubuntu系统使用的是ufw防火墙 必要操作 linux系统防火墙开放相
  • AOP之5种增强方法应用范例

    林炳文Evankaka原创作品 转载请注明出处http blog csdn net evankaka Spring AOP 提供了 5 种类型的通知 它们分别是 Before Advice 前置通知 After Returning Advi