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-> ...
随机推荐
- JS 对象的三种创建方式
变量 instanceof 类型的名字----->布尔类型,true就是这种类型,false不是这种类型 在当前的对象的方法中,可以使用this关键字代表当前的对象 1.调用系统的构造函数创 ...
- JUC包下CountDownLatch学习笔记
CountDownLatch的作用是能使用多个线程进来之后,且线程任务执行完毕之后,才执行, 闭锁(Latch):一种同步方法,可以延迟线程的进度直到线程到达某个终点状态.通俗的讲就是,一个闭锁相当于 ...
- Android RecyclerView组件和 Spinner(下拉列表框)
1.RecyclerView <1>知识点介绍 RecyclerView 比 ListView 更高级且更具灵活性. 它是一个用于显示庞大数据集的容器,可通过保持有限数量的视图进行非常有效 ...
- webpack 打包css报错 Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead
是webpack4和extract-text-webpack-plugin的兼容性问题 执行命令:npm install extract-text-webpack-plugin@next --save ...
- PHP验证身份信息
$code = 'code'; $patt = "/^[1-9]\d{5}(19|20)\d{2}((0[1-9])|(10|11|12))([012](\d|(30|31)))\d{3}[ ...
- JAVA 使用Dom4j 解析XML
[转自] http://blog.csdn.net/yyywyr/article/details/38359049 解析XML的方式有很多,本文介绍使用dom4j解析xml. 1.环境准备 (1)下载 ...
- Heap — 20181120
363. Trapping Rain Water public class Solution { /** * @param heights: a list of integers * @return: ...
- server 2012 R2查询端口
1. win+r弹出运行对话框,输入cmd,打开cmd窗口 netstat -ano | findstr "80" (注80是你想要看查看的端口号) 就会输出包含80端口使用的情况 ...
- 如何添加网页QQ在线组件
免费开通QQ推广服务 复制代码到你想要展示的位置 粘贴,完成.
- tgz 文件解压
使用命令:tar zxvf ×××.tgz 即可进行解压 留作备忘