|
真爱的事业和真正的爱情一生只有一次,都值得我们温柔地相待,因为那种感觉是永远都无法复制的, 这世界真正属于你的东西其实并不多,你不好好珍惜,它便会离你而去,包括机遇,包括爱情,包括生命。 不要找任何理由, 当幸福在你身边的时候就抓住它,你就一定会很幸福! |
时 间 记 忆 |
« | August 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | | | |
|
blog名称:玻璃杯中的花生壳 日志总数:162 评论数量:249 留言数量:1 访问次数:824474 建立时间:2004年11月4日 |
 | | |
|
|
1、Spring只支持方法拦截,也就是说,只能在方法的前后进行拦截,而不能在属性前后进行拦截。2、Spring支持四种拦截类型:目标方法调用前(before),目标方法调用后(after),目标方法调用前后(around),以及目标方法抛出异常(throw)。3、前置拦截的类必须实现MethodBeforeAdvice接口,实现其中的before方法。4、后置拦截的类必须实现AfterReturningAdvice接口,实现其中的afterReturning方法。5、前后拦截的类必须实现MethodInterceptor接口,实现其中的invoke方法。前后拦截是唯一可以控制目标方法是否被真正调用的拦截类型,也可以控制返回对象。而前置拦截或后置拦截不能控制,它们不能印象目标方法的调用和返回。但是以上的拦截的问题在于,不能对于特定方法进行拦截,而只能对某个类的全部方法作拦截。所以下面引入了两个新概念:“切入点”和“引入通知”。6、”切入点“的定义相当于更加细化地规定了哪些方法被哪些拦截器所拦截,而并非所有的方法都被所有的拦截器所拦截。在ProxyFactoryBean的属性中,interceptorNames属性的对象也由拦截(Advice)变成了引入通知(Advisor),正是在Advisor中详细定义了切入点(PointCut)和拦截(Advice)的对应关系,比如常见的基于名字的切入点匹配(NameMatchMethodPointcutAdvisor类)和基于正则表达式的切入点匹配(RegExpPointcutAdvisor类)。这些切入点都属于”静态切入点“,因为他们只在代理创建的时候被创建一次,而不是每次运行都创建。
下面我们进行实例的开发
首先创建业务接口:
500)this.width=500'>package AdvisorTest;500)this.width=500'>500)this.width=500'>500)this.width=500'>public interface Shopping ...{500)this.width=500'> public String buySomething(String type);500)this.width=500'> public String buyAnything(String type);500)this.width=500'> public void testException();500)this.width=500'>}500)this.width=500'>
下面是业务实现类,我们的通知就是以这些实现类作为切面,在业务方法前后加入我们的通知代码
500)this.width=500'>package AdvisorTest;500)this.width=500'>500)this.width=500'>500)this.width=500'>public class ShoppingImpl implements Shopping ...{500)this.width=500'> private Customer customer;500)this.width=500'>500)this.width=500'> public Customer getCustomer() ...{500)this.width=500'> return customer;500)this.width=500'> }500)this.width=500'>500)this.width=500'> public void setCustomer(Customer customer) ...{500)this.width=500'> this.customer = customer;500)this.width=500'> }500)this.width=500'>500)this.width=500'> public String buySomething(String type) ...{500)this.width=500'> System.out.println(this.getCustomer().getName()+" bye "+type+" success");500)this.width=500'> return null;500)this.width=500'> }500)this.width=500'> 500)this.width=500'>500)this.width=500'> public String buyAnything(String type) ...{500)this.width=500'> System.out.println(this.getCustomer().getName()+" bye "+type+" success");500)this.width=500'> return null;500)this.width=500'>500)this.width=500'> }500)this.width=500'>500)this.width=500'> public void testException()...{500)this.width=500'> throw new ClassCastException();500)this.width=500'> }500)this.width=500'>}500)this.width=500'>
(1)前置通知
配置了前置通知的bean,在执行业务方法前,均会执行前置拦截器的before方法
500)this.width=500'>package AdvisorTest;500)this.width=500'>500)this.width=500'>import java.lang.reflect.Method;500)this.width=500'>500)this.width=500'>import org.springframework.aop.MethodBeforeAdvice;500)this.width=500'>//前置通知500)this.width=500'>500)this.width=500'>public class WelcomeAdvice implements MethodBeforeAdvice ...{500)this.width=500'>500)this.width=500'> public void before(Method method, Object[] args, Object obj)500)this.width=500'>500)this.width=500'> throws Throwable ...{500)this.width=500'> String type=(String)args[0];500)this.width=500'> System.out.println("Hello welcome to bye "+type);500)this.width=500'>500)this.width=500'> }500)this.width=500'>500)this.width=500'>}500)this.width=500'>
(2)后置通知配置了前置通知的bean,在执行业务方法前,均会执行前置拦截器的afterReturnning方法
500)this.width=500'>package AdvisorTest;500)this.width=500'>500)this.width=500'>import java.lang.reflect.Method;500)this.width=500'>500)this.width=500'>import org.springframework.aop.AfterReturningAdvice;500)this.width=500'>import org.springframework.aop.MethodBeforeAdvice;500)this.width=500'>//后置通知500)this.width=500'>500)this.width=500'>public class ThankYouAdvice implements AfterReturningAdvice ...{500)this.width=500'>500)this.width=500'> public void afterReturning(Object obj, Method method, Object[] arg1,500)this.width=500'>500)this.width=500'> Object arg2) throws Throwable ...{500)this.width=500'> 500)this.width=500'> String type=(String)arg1[0];500)this.width=500'> System.out.println("Hello Thankyou to bye "+type);500)this.width=500'> }500)this.width=500'> 500)this.width=500'>500)this.width=500'>}500)this.width=500'>
(3)环绕通知
配置了前置通知的bean,在执行业务方法前后,均会执行前置拦截器的invoke方法
需要注意的是必须调用目标方法,如不调用,目标方法将不被执行
500)this.width=500'>package AdvisorTest;500)this.width=500'>500)this.width=500'>import org.aopalliance.intercept.MethodInterceptor;500)this.width=500'>import org.aopalliance.intercept.MethodInvocation;500)this.width=500'>500)this.width=500'>500)this.width=500'>public class MethodAdvisor implements MethodInterceptor ...{500)this.width=500'>500)this.width=500'>500)this.width=500'> public Object invoke(MethodInvocation invocation) throws Throwable ...{500)this.width=500'> String str=(String)invocation.getArguments()[0];500)this.width=500'> System.out.println("this is before"+str+" in MethodInterceptor");500)this.width=500'> Object obj=invocation.proceed(); //调用目标方法,如不调用,目标方法将不被执行500)this.width=500'> System.out.println("this is after"+str+" in MethodInterceptor");500)this.width=500'> return null;500)this.width=500'> }500)this.width=500'>500)this.width=500'>}500)this.width=500'>
(4)异常通知
ThrowsAdvice是一个标示接口,我们可以在类中定义一个或多个,来捕获定义异常通知的bean抛出的异常,并在抛出异常前执行相应的方法
public void afterThrowing(Throwable throwa){}
或者
public void afterThrowing(Method method,Object[] args,Object target,Throwable throwable){
500)this.width=500'>package AdvisorTest;500)this.width=500'>500)this.width=500'>import org.springframework.aop.ThrowsAdvice;500)this.width=500'>500)this.width=500'>500)this.width=500'>public class ExceptionAdvisor implements ThrowsAdvice ...{500)this.width=500'>500)this.width=500'> public void afterThrowing(ClassCastException e)...{500)this.width=500'> System.out.println("this is from exceptionAdvisor");500)this.width=500'> }500)this.width=500'>}500)this.width=500'>
配置文件
500)this.width=500'><?xml version="1.0" encoding="UTF-8"?>500)this.width=500'><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >500)this.width=500'><beans>500)this.width=500'> <bean id="customer" class="AdvisorTest.Customer">500)this.width=500'> <constructor-arg index="0">500)this.width=500'> <value>gaoxiang</value>500)this.width=500'> </constructor-arg>500)this.width=500'> <constructor-arg index="1">500)this.width=500'> <value>26</value>500)this.width=500'> </constructor-arg>500)this.width=500'> </bean>500)this.width=500'> 500)this.width=500'> <bean id="shoppingImpl" class="AdvisorTest.ShoppingImpl">500)this.width=500'> <property name="customer">500)this.width=500'> <ref local="customer"/>500)this.width=500'> </property>500)this.width=500'> </bean>500)this.width=500'>500)this.width=500'><!-- 前置通知 -->500)this.width=500'><bean id="welcomeAdvice" class="AdvisorTest.WelcomeAdvice"/>500)this.width=500'><bean id="welcomeAdviceShop" class="org.springframework.aop.framework.ProxyFactoryBean">500)this.width=500'> <property name="proxyInterfaces">500)this.width=500'> <value>AdvisorTest.Shopping</value>500)this.width=500'> </property>500)this.width=500'> <property name="target">500)this.width=500'> <ref local="shoppingImpl"/>500)this.width=500'> </property>500)this.width=500'> <property name="interceptorNames">500)this.width=500'> < |
|
|
回复:Spring AOP四种创建通知(拦截器)类型实例 |
[ 2008/6/4 17:03:25 | By: wanglifengchao@126.c(游客) ] |
| » 1 »
| | |
|