AOP通知类型
来源:互联网 发布:海文网络计划软件教程 编辑:程序博客网 时间:2024/06/01 19:03
分类
前置通知
- 在目标类的方法执行之前执行。
- 配置文件信息:
- 应用:可以对方法的参数来做校验
最终通知
- 在目标类的方法执行之后执行,如果程序出现了异常,最终通知也会执行。
- 在配置文件中编写具体的配置:
- 应用:例如像释放资源
后置通知
- 方法正常执行后的通知。
- 在配置文件中编写具体的配置:
- 应用:可以修改方法的返回值
异常抛出通知
- 在抛出异常后通知
- 在配置文件中编写具体的配置:
- 应用:包装异常的信息
环绕通知
- 方法的执行前后执行。
- 在配置文件中编写具体的配置:
- 要注意:目标的方法默认不执行,需要使用ProceedingJoinPoint对来让目标对象的方法执行。
注意:AOP依赖与IoC,在spring里不是使用注解就是配置xml,所以,下面会用到配置文件进行配置通知
步骤
使用maven导包spring-context,会自动引入spring-aop
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.6.RELEASE</version></dependency>
提供代理对象PhoneImpl.java
public class PhoneImpl { public void product5S() { System.out.println("生产iPhone 5S中"); } //为下面的异常通知使用 public void testException() { //设置异常 int i=0/10; System.out.println("这是异常下面的代码"); }}
提供一个applicationContext.xml
,提供一个Test.java
测试类
<?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:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"></beans>
前置通知
提供代理对象BeforeProxy.java
import java.lang.reflect.Method;import org.springframework.aop.MethodBeforeAdvice;public class BeforeProxy implements MethodBeforeAdvice{ @Override public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable { System.out.println("前置通知"); }}
配置文件applicationContext.xml中配置前置通知
<!-- 创建要代理的对象 一下的id随便起名字--> <bean id="phone" class="com.phone.PhoneImpl"></bean> <!-- 创建增强对象,也就是通知对象 --> <bean id="before" class="com.proxy.BeforeProxy"></bean> <!-- 处理要代理的对象与增强对象之间的关系 --> <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 设置要代理的对象,也就是目标对象 --> <property name="target" ref="phone"></property> <!-- 设置拦截器,也就是增强对象 注意使用的是value属性--> <property name="interceptorNames" value="before"></property> <!-- 如果为true表示jdk代理,要有接口,如果为false表示可以没有接口 --> <property name="optimize" value="false"></property> </bean>
测试
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); PhoneImpl phone=(PhoneImpl)applicationContext.getBean("proxy"); phone.product5S();
运行结果
前置通知生产iPhone 5S中
后置通知
提供后置通知对象AfterProxy.java
,注意实现的接口
import java.lang.reflect.Method;import org.springframework.aop.AfterReturningAdvice;public class AfterProxy implements AfterReturningAdvice{ @Override public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable { System.out.println("后置通知"); }}
配置文件applicationContext.xml中增加bean
<!-- 创建要代理的对象 一下的id随便起名字--> <bean id="phone" class="com.henu.phone.PhoneImpl"></bean> <!-- 创建增强对象,也就是通知对象 --> <bean id="before" class="com.henu.proxy.BeforeProxy"></bean> <!--增加的地方--> <bean id="after" class="com.henu.proxy.AfterProxy"></bean> <!-- 处理要代理的对象与增强对象之间的关系 --> <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 设置要代理的对象,也就是目标对象 --> <property name="target" ref="phone"></property> <!-- 设置拦截器,也就是增强对象 注意使用的是value属性--> <!--修改的地方,同时提供前置和后置通知,这个地方为什么不用ref引用呢,如果用ref会报错,这里可以引入多个对象,如果用ref只能引入一个对象--> <property name="interceptorNames" value="after,before"></property> <!-- 如果为true表示jdk代理,要有接口,如果为false表示可以没有接口 --> <property name="optimize" value="false"></property> </bean>
运行结果
前置通知生产iPhone 5S中后置通知
环绕通知
提供RoundProxy.java
import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;public class RoundProxy implements MethodInterceptor{ //可以替代目标方法 @Override public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("环绕通知"); //如果没有下面这些,执行的时候目标方法会被替代,只显示上面的一句话 invocation.proceed();//执行原来的方法 return null; }}
修改配置文件
<!-- 创建要代理的对象 一下的id随便起名字--> <bean id="phone" class="com.henu.phone.PhoneImpl"></bean> <!-- 创建增强对象,也就是通知对象 --> <bean id="before" class="com.henu.proxy.BeforeProxy"></bean> <bean id="after" class="com.henu.proxy.AfterProxy"></bean> <bean id="round" class="com.henu.proxy.RoundProxy"></bean> <!-- 处理要代理的对象与增强对象之间的关系 --> <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 设置要代理的对象,也就是目标对象 --> <property name="target" ref="phone"></property> <!-- 设置拦截器,也就是增强对象 注意使用的是value属性--> <property name="interceptorNames" value="after,before,round"></property> <!-- 如果为true表示jdk代理,要有接口,如果为false表示可以没有接口 --> <property name="optimize" value="false"></property> </bean>
运行结果
前置通知环绕通知生产iPhone 5S中后置通知
异常通知
提供异常通知代理类ExceptionProxy.java
import java.lang.reflect.Method;import org.springframework.aop.ThrowsAdvice;//该接口没有任何方法需要实现,需要自己写public class ExceptionProxy implements ThrowsAdvice{ /*public void afterThrowing(Throwable throwable) { }*/ public void afterThrowing(Method m,Object[] os,Object obj,Throwable throwable) { System.out.println("异常通知"); }}
修改配置文件
<!-- 创建要代理的对象 一下的id随便起名字--> <bean id="phone" class="com.henu.phone.PhoneImpl"></bean> <!-- 创建增强对象,也就是通知对象 --> <bean id="before" class="com.henu.proxy.BeforeProxy"></bean> <bean id="after" class="com.henu.proxy.AfterProxy"></bean> <bean id="round" class="com.henu.proxy.RoundProxy"></bean> <bean id="throwss" class="com.henu.proxy.ExceptionProxy"></bean> <!-- 处理要代理的对象与增强对象之间的关系 --> <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 设置要代理的对象,也就是目标对象 --> <property name="target" ref="phone"></property> <!-- 设置拦截器,也就是增强对象 注意使用的是value属性--> <property name="interceptorNames" value="after,before,round,throwss"></property> <!-- 如果为true表示jdk代理,要有接口,如果为false表示可以没有接口 --> <property name="optimize" value="false"></property> </bean>
修改测试类Test.java
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); PhoneImpl phone=(PhoneImpl)applicationContext.getBean("proxy"); //要修改的地方 phone.testException();
测试结果,打印出了 异常通知
前置通知环绕通知异常通知Exception in thread "main" java.lang.ArithmeticException: / by zero at com.henu.phone.PhoneImpl.testException(PhoneImpl.java:10) at com.henu.phone.PhoneImpl$$FastClassBySpringCGLIB$$edc957f1.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:125) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at com.henu.proxy.RoundProxy.invoke(RoundProxy.java:12) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:52) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653) at com.henu.phone.PhoneImpl$$EnhancerBySpringCGLIB$$d04c134a.testException(<generated>) at com.henu.proxy.Test.main(Test.java:12)
最终通知
无论目标方法是否遇到异常都会执行,相当于代码中的finnaly
。。。这个以后补充。。。
阅读全文
0 0
- AOP的通知类型
- AOP通知类型
- spring aop的五种通知类型
- Spring 配置使用 - AOP 通知类型
- spring aop的五种通知类型
- spring aop的五种通知类型
- spring aop的五种通知类型
- aop 通知
- aop 通知
- Spring AOP四种创建通知(拦截器)类型实例
- Spring AOP四种创建通知(拦截器)类型实例
- Spring AOP四种创建通知(拦截器)类型实例
- Spring AOP四种创建通知(拦截器)类型实例
- Spring AOP四种创建通知(拦截器)类型实例
- spring aop的五种通知类型(基于XML)
- Spring AOP实例(五大通知类型)
- Spring AOP的八个概念、五个通知类型、AOP的第一种实现方式
- Spring AOP-通知-前置通知
- 2017/8/7 离线赛
- myeclipse中svn突然失效问题
- 用memset清空数组时要注意的问题
- Android获取手机存储状态
- 日常篇
- AOP通知类型
- F
- 递归 汉诺塔问题
- android.mk的配置说明
- 51Nod(1086)
- 硬盘,u盘等存储设备.正确方法
- WARN:oejw.WebAppContext:Failed startup of context o.m.j.p.JettyWebAppContext……
- 中标麒麟V6虚拟机安装和网络配置
- Android图片选择器