20_AOP_Advice增强1(前置、后置、环绕)
【增强的类型】
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(前置、后置、环绕)的更多相关文章
- Spring -- aop(面向切面编程),前置&后置&环绕&抛异常通知,引入通知,自动代理
1.概要 aop:面向方面编程.不改变源代码,还为类增加新的功能.(代理) 切面:实现的交叉功能. 通知:切面的实际实现(通知要做什么,怎么做). 连接点:应用程序执行过程期间,可以插入切面的地点. ...
- spring 切面 前置后置通知 环绕通知demo
环绕通知: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http:// ...
- AOP 环绕通知 集成了前置 后置 返回通知等功能
AOP 环绕通知 集成了前置 后置 返回通知等功能
- Spring Bean前置后置处理器的使用
Spirng中BeanPostProcessor和InstantiationAwareBeanPostProcessorAdapter两个接口都可以实现对bean前置后置处理的效果,那这次先讲解一下B ...
- pytest_前置后置
今天总结下pytest,pytest简直就是python自动化中的高富帅,各种操作,哈哈 这次总结主要涉及到了以下几点: 1.unittest中的setUp.tearDown.setUpClass.t ...
- unittest的前置后置,pytest的fixture和共享机制conftest.py
Unittest setUp/tearDown setUp当中得到的变量,用self.xxx = value传递给测试用例 setUpClass/tearDownClass setupClass当中得 ...
- 实现简单的AOP前置后置增强
AOP操作是我们日常开发经常使用到的操作,例如都会用到的spring事务管理.今天我们通过一个demo实现对一个类的某一个方法进行前置和后置的增强. //被增强类 public class PetSt ...
- C: printf参数执行顺序与前置后置自增自减的影响
起源: 今天在了解副作用side-effect的过程中,看到了下面的网页,把我带到了由printf引起的一系列问题,纠结了一整天,勉强弄懂. 第一个代码没什么好解释的.而第二个printf(" ...
- android实现前置后置摄像头相互切换
首先自定义一个继承自SurfaceView并且实现了SurfaceHolder.Callback接口的组件: public class CameraView extends SurfaceView i ...
- thinkphp5使用前置后置操作
下面举个例子,前置删除的例子 模型事件只可以在调用模型的方法才能生效,使用查询构造器通过Db类操作是无效的 控制器中实例化类 $cate=model('cate'); $cate-> ...
随机推荐
- bootstrap的其他
情境文本颜色 <p class="text-muted">...</p> <p class="text-primary">. ...
- CentOS 中 redis 安装
第一步:下载redis安装包 wget http://download.redis.io/releases/redis-4.0.6.tar.gz [root@hadoop110 桌面]# wget h ...
- js 获取 屏幕 可用高度...
document.documentElement.clientWidth 此方法适用于手机... document.documentElement.clientHeight (浏览器(手机或电脑)可用 ...
- codeforces 1072D Minimum path bfs+剪枝 好题
题目传送门 题目大意: 给出一幅n*n的字符,从1,1位置走到n,n,会得到一个字符串,你有k次机会改变某一个字符(变成a),求字典序最小的路径. 题解: (先吐槽一句,cf 标签是dfs题????) ...
- gym 100589A queries on the Tree 树状数组 + 分块
题目传送门 题目大意: 给定一颗根节点为1的树,有两种操作,第一种操作是将与根节点距离为L的节点权值全部加上val,第二个操作是查询以x为根节点的子树的权重. 思路: 思考后发现,以dfs序建立树状数 ...
- Codeforces - 600E 树上启发式合并
题意:求每一个子树存在最多颜色的颜色代号和(可重复) 本题是离线统计操作,因此可以直接合并重儿子已达到\(O(nlogn)\)的复杂度 PS.不知道什么是启发式合并的可以这样感受一下:进行树链剖分,分 ...
- UVA - 10589 构造最优化函数 DP好题
题意:给定一个图,节点可以放灯,要求用最少的灯覆盖所有的边(每盏灯能覆盖该节点邻接的边),满足条件的同时求该前提下尽量多的被两盏灯照亮的边数 条件二转化为求尽量少的被一盏灯照亮的边数,两个条件都是求m ...
- MBR为什么不支持3T硬盘
MBR,全称为Master Boot Record,即硬盘的主引导记录.(是管理硬盘分区的一种模式.升级版是GPT) MBR保存在硬盘的第1个扇区(即硬盘的0柱面.0磁头.1扇区).它由三个部分组成, ...
- [转] Node.js的线程和进程
[From] http://www.admin10000.com/document/4196.html 前言 很多Node.js初学者都会有这样的疑惑,Node.js到底是单线程的还是多线程的?通过本 ...
- scrapy_redis之官网列子domz
一. domz.py from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, ...