【增强的类型】

1.前置增强:org.springframework.aop.BeforeAdvice

由于Spring只支持方法级别的增强,所以MethodBeforeAdvice是目前可用的前置增强,表示在目标方法执行前执行前置增强,BeforeAdvice是为了将来版本扩展需要而定义的。

2.后置增强:org.springframework.aop.AfterReturningAdvice

表示在目标方法执行后执行增强。

3.环绕增强:org.aopalliance.intercept.MethodInterceptor

表示在目标方法执行前后执行增强。

4.异常抛出增强:org.springframework.aop.ThrowsAdvice

表示在目标方法抛出异常时执行增强。

5.引介增强:org.springframework.aop.IntroductionInterceptor

在目标类中添加一些新的属性和方法。

【前置、后置、环绕增强整个工程】

【车子接口 Car.java】

package com.Higgin.part1;

/**
* 车子接口
*/
public interface Car {
public void drive();
}

【具体奔驰车类:BenzCar.java】

package com.Higgin.part1;

/**
* 奔驰车类
* 我们希望测试奔驰车在执行drive()方法前、后、前后增强的情况
*/
public class BenzCar implements Car{ @Override
public void drive() {
System.out.println("【业务方法】奔驰车在行驶....");
} }

【前置增强类】

package com.Higgin.part1;

import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice; /**
* 前置增强类
* 实现的是:MethodBeforeAdvice接口
*/
public class DriveBeforeAdvice implements MethodBeforeAdvice{ /**
* method:目标类的方法
* args:目标类方法的参数
* obj:目标类的实例
*/
@Override
public void before(Method method, Object[] args, Object obj)throws Throwable {
System.out.println("【前置增强】开车前自动放音乐~~~");
}
}

【测试前置增强类1:TestBeforeAdvice】

package com.Higgin.part1.Test;

import org.springframework.aop.BeforeAdvice;
import org.springframework.aop.framework.ProxyFactory;
import com.Higgin.part1.BenzCar;
import com.Higgin.part1.Car;
import com.Higgin.part1.DriveBeforeAdvice; /**
* 测试 前置增强
*/
public class TestBeforeAdvice{
public static void main(String[] args) {
Car benz=new BenzCar(); //目标对象
BeforeAdvice driveBeforeAdvice=new DriveBeforeAdvice(); //前置增强 ProxyFactory pf=new ProxyFactory(); //1.Spring代理工厂 pf.setTarget(benz); //2.设置代理目标对象 pf.addAdvice(driveBeforeAdvice); //3.为代理对象添加增强 Car carProxy=(Car) pf.getProxy(); //4.生成代理实例 carProxy.drive(); }
}

[ 运行结果 ]

【测试前置增强类2:用Spring的xml配置文件方式:TestBeforeAdviceXml.java】

package com.Higgin.part1.Test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.Higgin.part1.Car; public class TestBeforeAdviceXml {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("part1.xml");
Car car=(Car) context.getBean("benzCar1");
car.drive();
}
}

【测试前置增强类2:用Spring的xml配置文件方式的配置文件:part1.xml】

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd"> <!-- 要增强的目标对象 -->
<bean id="target" class="com.Higgin.part1.BenzCar"/> <!-- 前置增强的类 -->
<bean id="driveBeforeAdvice" class="com.Higgin.part1.DriveBeforeAdvice" /> <!-- Spring代理工厂的成员变量配置(前置增强)-->
<bean id="benzCar1" class="org.springframework.aop.framework.ProxyFactoryBean"
p:proxyInterfaces="com.Higgin.part1.Car"
p:interceptorNames="driveBeforeAdvice"
p:target-ref="target"
/> </beans>

[ 运行结果 ]

【后置增强类:DriveAfterAdvice.java】

package com.Higgin.part1;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

/**
* 后置增强类
* 实现的是:AfterReturningAdvice
*/
public class DriveAfterAdvice implements AfterReturningAdvice{ @Override
public void afterReturning(Object returnObj, Method method, Object[] args, Object obj) throws Throwable {
System.out.println("【后置增强】停车后自动关闭音乐~~~");
}
}

【测试后置增强类1:TestAfterAdvice.java】

package com.Higgin.part1.Test;

import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.BeforeAdvice;
import org.springframework.aop.framework.ProxyFactory; import com.Higgin.part1.BenzCar;
import com.Higgin.part1.Car;
import com.Higgin.part1.DriveAfterAdvice;
import com.Higgin.part1.DriveBeforeAdvice; public class TestAfterAdvice {
public static void main(String[] args) {
Car benz=new BenzCar(); //目标对象
BeforeAdvice driveBeforeAdvice=new DriveBeforeAdvice(); //前置增强
AfterReturningAdvice driveAfterAdvice=new DriveAfterAdvice(); //后置增强 ProxyFactory pf=new ProxyFactory(); //1.Spring代理工厂 pf.setTarget(benz); //2.设置代理目标 pf.addAdvice(driveBeforeAdvice); //3.为代理对象添加 前 置增强
pf.addAdvice(driveAfterAdvice); //3.为代理对象添加 后 置增强 Car carProxy=(Car) pf.getProxy(); //4.生成代理实例 carProxy.drive();
}
}

【运行结果】

【测试后置增强类2:用Spring的xml配置文件方式:TestAfterAdviceXml.java】

package com.Higgin.part1.Test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.Higgin.part1.Car; public class TestAfterAdviceXml {
public static void main(String[] args) {
ApplicationContext context =new ClassPathXmlApplicationContext("part1.xml");
Car benz=(Car) context.getBean("benzCar2");
benz.drive();
}
}

【测试后置增强类2:用Spring的xml配置文件方式的配置文件:part1.xml】

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd"> <!-- 要增强的目标对象 -->
<bean id="target" class="com.Higgin.part1.BenzCar"/> <!-- 前置增强的类 -->
<bean id="driveBeforeAdvice" class="com.Higgin.part1.DriveBeforeAdvice" />
<!-- 后置增强的类 -->
<bean id="dirveAfterAdvice" class="com.Higgin.part1.DriveAfterAdvice" /> <!-- Spring代理工厂的成员变量配置(后置增强+前置增强) -->
<bean id="benzCar2" class="org.springframework.aop.framework.ProxyFactoryBean"
p:proxyInterfaces="com.Higgin.part1.Car"
p:interceptorNames="driveBeforeAdvice,dirveAfterAdvice"
p:target-ref="target"
/> </beans>

[ 运行结果 ]

【环绕增强类:DriveAroundAdvice.java】

package com.Higgin.part1;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation; /**
* 环绕增强
* 实现的接口:MethodInterceptor
* 注意:需要导入jar包:aopalliance-1.0.jar
*/
public class DriveAroundAdvice implements MethodInterceptor{ @Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("【前置增强】开车前自动打开音乐~~~");
Object obj=invocation.proceed(); //通过反射执行目标的业务方法
System.out.println("【后置增强】停车后自动关闭音乐~~~");
return obj;
} }

【环绕增强测试类1:TestAroundAdvice.java】

package com.Higgin.part1.Test;

import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.framework.ProxyFactory; import com.Higgin.part1.BenzCar;
import com.Higgin.part1.Car;
import com.Higgin.part1.DriveAroundAdvice; public class TestAroundAdvice {
public static void main(String[] args) {
Car benzCar=new BenzCar();
MethodInterceptor driveAroundAdvice=new DriveAroundAdvice(); ProxyFactory pf=new ProxyFactory(); pf.setTarget(benzCar); pf.addAdvice(driveAroundAdvice); Car carProxy=(Car) pf.getProxy(); carProxy.drive();
}
}

[ 运行结果 ]

【测试环绕增强类2:用Spring的xml配置文件方式:TestAroundAdviceXml.java】

package com.Higgin.part1.Test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.Higgin.part1.Car; public class TestAroundAdviceXml {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("part1.xml");
Car car=(Car) context.getBean("benzCar3");
car.drive();
}
}

【测试环绕增强类2:用Spring的xml配置文件方式的配置文件:part1.xml】

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd"> <!-- 要增强的目标对象 -->
<bean id="target" class="com.Higgin.part1.BenzCar"/> <!-- 环绕增强的类 -->
<bean id="driveAroundAdvice" class="com.Higgin.part1.DriveAroundAdvice"/> <!-- Spring代理工厂的成员变量配置(环绕增强) -->
<bean id="benzCar3" class="org.springframework.aop.framework.ProxyFactoryBean"
p:proxyInterfaces="com.Higgin.part1.Car"
p:interceptorNames="driveAroundAdvice"
p:target-ref="target"
/> </beans>

[ 运行结果 ]

【分析】

1.关于spring的xml配置文件的分析

其中的ProxyFactoryBean类是FactoryBean的实现类,

FactoryBean负责实例化一个Bean,

ProxyFactoryBean负责为其他Bean创建代理实例,它内部使用ProxyFactory来完成这一工作。

ProxyFactoryBean的几个可配置属性(成员变量)

  target:代理的目标对象

  proxyInterfaces:代理需要实现的接口,可以是多个接口。该属性该有一个别名interfaces。

  interceptor:需要织入目标对象的Bean列表。采用Bean的名称指定。这些Bean必须是实现了org.aoplliance.interceptor.MethodInterceptor或者org.springframework.Advisor的Bean,配置中的顺序对应调用的顺序。

  singleton:返回的代理是否是单例,默认单例。

  optimize:为true时,强制使用Cglib代理,对于Singleton的代理,建议使用CGlib。对于其他作用域类型的代理,最好使用JDK代理。(CGLib创建代理时速度慢,而创建出来的代理对象运行效率高,JDK代理相反)

  proxyTargetClass:是否对类进行代理(而不是对接口进行代理),设置为true时,使用CGLib代理。

  

20_AOP_Advice增强1(前置、后置、环绕)的更多相关文章

  1. Spring -- aop(面向切面编程),前置&后置&环绕&抛异常通知,引入通知,自动代理

    1.概要 aop:面向方面编程.不改变源代码,还为类增加新的功能.(代理) 切面:实现的交叉功能. 通知:切面的实际实现(通知要做什么,怎么做). 连接点:应用程序执行过程期间,可以插入切面的地点. ...

  2. spring 切面 前置后置通知 环绕通知demo

    环绕通知: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http:// ...

  3. AOP 环绕通知 集成了前置 后置 返回通知等功能

    AOP 环绕通知 集成了前置 后置 返回通知等功能

  4. Spring Bean前置后置处理器的使用

    Spirng中BeanPostProcessor和InstantiationAwareBeanPostProcessorAdapter两个接口都可以实现对bean前置后置处理的效果,那这次先讲解一下B ...

  5. pytest_前置后置

    今天总结下pytest,pytest简直就是python自动化中的高富帅,各种操作,哈哈 这次总结主要涉及到了以下几点: 1.unittest中的setUp.tearDown.setUpClass.t ...

  6. unittest的前置后置,pytest的fixture和共享机制conftest.py

    Unittest setUp/tearDown setUp当中得到的变量,用self.xxx = value传递给测试用例 setUpClass/tearDownClass setupClass当中得 ...

  7. 实现简单的AOP前置后置增强

    AOP操作是我们日常开发经常使用到的操作,例如都会用到的spring事务管理.今天我们通过一个demo实现对一个类的某一个方法进行前置和后置的增强. //被增强类 public class PetSt ...

  8. C: printf参数执行顺序与前置后置自增自减的影响

    起源: 今天在了解副作用side-effect的过程中,看到了下面的网页,把我带到了由printf引起的一系列问题,纠结了一整天,勉强弄懂. 第一个代码没什么好解释的.而第二个printf(" ...

  9. android实现前置后置摄像头相互切换

    首先自定义一个继承自SurfaceView并且实现了SurfaceHolder.Callback接口的组件: public class CameraView extends SurfaceView i ...

  10. thinkphp5使用前置后置操作

    下面举个例子,前置删除的例子   模型事件只可以在调用模型的方法才能生效,使用查询构造器通过Db类操作是无效的   控制器中实例化类   $cate=model('cate'); $cate-> ...

随机推荐

  1. 24.Letter Combinations of a Phone Number(电话号对应的字符组合)

    Level:   Medium 题目描述: Given a string containing digits from 2-9 inclusive, return all possible lette ...

  2. C++11 中的 Defaulted 和 Deleted 函数

    http://blog.jobbole.com/103669/ C++11 中的 Defaulted 和 Deleted 函数 2016/07/21 · C/C++, 开发 · C++ 分享到:3   ...

  3. Python之freshman02

    内置方法:https://docs.python.org/3/library/functions.html?highlight=built#abs 一.数学运算 1.abs()-取绝对值 2.divm ...

  4. 01、前端需要注意哪些SEO?

    1.前端需要注意哪些SEO? 1)设置网站TDK标签的设置 2)图片img标签必须加上alt属性 3)h1~h6标签合理使用 4)a标签增加rel="nofollow" 5) 安装 ...

  5. 递归缓存技术,缓存机制Memoization

    先看一下代码: 再看一下执行时间: 可以看出第一个阶乘的执行时间是3ms,后面的由于缓存了之前的计算结果,所以直接返回结果. 原理就是缓存之前的计算,避免重复计算.关键在于建立缓存数组. 可以看一下执 ...

  6. copy模拟

    1.copy是浅复制,只复制一层:而deepcopy是所有层都复制,适用于lis嵌套listt的复制.两都均是函数.

  7. ASP.NET中MD5的加密方式很简单

    在ASP.NET中MD5的加密方式很简单,代码如下: FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5&quo ...

  8. css 之 BFC

    1,定义 BFC为块级格式化上下文,也就是一块区域内的封闭空间,里面元素无论怎么样,都不会影响外部元素. 2,触发条件 html 根元素 display的值为 inline-block.table-c ...

  9. Oracle 11g 记录DML错误数据

    [From] https://oracle-base.com/articles/10g/dml-error-logging-10gr2 需要记录下大量DML操作中出错的具体record,看到有两种方案 ...

  10. hdu 1237 简单计算器(栈处理)

    简单计算器 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...