【增强的类型】

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. WPF:CheckBox竖向的滑块效果

    原文:WPF:CheckBox竖向的滑块效果 之前做了一个横向的滑块效果,<WPF:CheckBox滑块效果>,其实我觉得那个不好看,今天又做了一个竖向的玩. <Style Targ ...

  2. 绿色版NVM安装与配置详细说明

      绿色版本(不需要安装,直接解压,然后配置环境变量等) 由于最初发布的nvm并不支持window,所以如果希望可以像在*nix上一样控制node的版本,有两种选择: nvm-windows nodi ...

  3. BZOJ - 2844 线性基

    题意:求给定的数在原数组中的异或组合中的排名(非去重) 因为线性基中\(b[j]=1\)表示该位肯定存在,所以给定的数如果含有该位,由严格递增和集合枚举可得,排名必然加上\(2^j\)(不是完全对角就 ...

  4. nodejs 休眠 / 暂停执行指定毫秒

    //************** 暂停 / 休眠指定毫秒值 *********************************// milliSeconds 暂停 / 休眠多少毫秒async func ...

  5. 2.5 Go错误处理

    defer import "fmt" func testDefer(){ defer fmt.Println() defer fmt.Println() fmt.Println() ...

  6. Oracle 的加减法函数

    原文:https://blog.csdn.net/chenghaibing2008/article/details/37873117 加法   select sysdate,add_months(sy ...

  7. APP在实际开发中应注意的关键点

    在APP开发过程中,开发者比较注重的是功能模块的实现,从而忽略了APP的设计问题,特别是企业开发APP,但是,APP设计是APP开发中非常重要的一个环节,APP界面设计直接影响到APP用户的感官,因此 ...

  8. python3初探

      官方网站:https://www.python.org/ 类库大全:https://pypi.python.org/pypi 基础类库:https://docs.python.org/3/libr ...

  9. Immutable-不变模式与不变类

    不变模式的定义 一个对象在创建之后就不再变化,就是所谓的不变模式(Immutable Pattern): 一般来讲,一个对象要么就是可变对象(Mutable Object),要么就是不变模式(Immu ...

  10. hibernateAPI详解

    1 Configuration package www.test.b_api; import org.hibernate.Session; import org.hibernate.SessionFa ...