日期:2014-05-20 浏览次数:20830 次
Spring的Advices
Advices实现了Aspect的真正逻辑。由于织入至Targets的实际不同,spring提供了不同的Advices,像Before Advice,After Advice,Around Advice,Throw Advice。
(1)、Before Advice
通过实现MethodBeforeAdvice来定义
(2)、After Advice
通过实现AfterReturningAdvice来定义
(3)、Around Advice
通过实现MethodInterceptor来定义
(4)、Throw Advice
通过实现ThrowsAdvice来定义
我们将使用一个代理的bean aaa,给这个代理的bean加上我们spring的advice,看看他的日志输出表现。我们通过代码示例来说明:
1、定义基本的advice Bean以及要被调用的类
(1)、beforeAdvice的Bean
?
package com.itcast.advice; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; /** * 调用方法之前 * */ public class LogBeforeAdvice implements MethodBeforeAdvice { public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("beforeAdvice 调用方法之前被执行!..........."); } }
?
(2)、afterAdvice的bean
?
package com.itcast.advice; import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; public class LogAfterAdvice implements AfterReturningAdvice { public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("afterAdvice 调用方法之后被执行!..........."); } }
?
(3)、Around advice的Bean
package com.itcast.advice; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; /** * 环绕通知 * */ public class LogAroundAdvice implements MethodInterceptor { public Object invoke(MethodInvocation mi) throws Throwable { Object result=null; System.out.println("around 调用方法之前...."); result=mi.proceed(); System.out.println("around 调用方法之后..."); return result; } }
?
(4)、Throw Advice的Bean
package com.itcast.advice; import java.lang.reflect.Method; import org.springframework.aop.ThrowsAdvice; /**抛出异常时候的通知*/ public class ThrowAdvice implements ThrowsAdvice { public void afterThrowing(Method method,Object[] args,Object target,Throwable subclass) { System.out.println("ThrowAdvice 记录异常..........."); } }
?
(5)、要被代理的类
package com.itcast.proxy; public class HelloSpeaker1 implements IHello { public void hi() { System.out.println("我在HelloSpeaker1中"); } public void hiAAA(String aaa) { System.out.println("我在HelloSpeaker1中---hiAAA["+aaa+"]"); } public void hiBBB(String bbb) throws Exception { System.out.println("我在HelloSpeaker1中---hiBBB["+bbb+"]"); throw new Exception("aaa"); } } package com.itcast.proxy; /** * 代理接口 * */ public interface IHello { public void hi(); public void hiAAA(String aaa); public void hiBBB(String bbb) throws Exception; }
?
2、在配置文件中声明我们的bean
<!-- 代理 --> <bean id="helloSpeaker1" class="com.itcast.proxy.HelloSpeaker1"></bean> <!-- 声明四种通知类型,其实就是你想加入到其他被代理程序执行逻辑中的代码 --> <bean id="beforeAdvice" class="com.itcast.advice.LogBeforeAdvice"/> <bean id="afterAdvice" class="com.itcast.advice.LogAfterAdvice"></bean> <bean id="aroundAdvice" class="com.itcast.advice.LogAroundAdvice"></bean> <bean id="throwAdvice" class="com.itcast.advice.ThrowAdvice"></bean> <!-- 基础的通知使用,这里强行给helloSpeaker1加上了advice通知 --> <bean id="aaa" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="helloSpeaker1"></property> <property name="interceptorNames"> <list> <value>aroundAdvice</value> <value>beforeAdvice</value> <value>afterAdvice</value> <value>throwAdvice</value> </list> </property> </bean>
?
3、在main函数中调用
package com.itcast.advice; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.itcast.proxy.IHello; public class AdviceMain { /**对于给基本的spring bean强行指定一批advice方法的调用展示**/ public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("bean-config.xml"); IHello h = (IHello)ctx.getBean("aaa"); h.hiAAA("测试配置aop的adivce"); System.out.println("进行抛出异常的adivce展示-=================="); try { h.hiBBB("测试抛出异常的advice"); } catch (Exception e) { } } }
?
4、控制台的显示
around 调用方法之前....
beforeAdvice 调用方法之前被执行!...........
我在HelloSpeaker1中---hiAAA[测试配置aop的adivce]
afterAdvice 调用方法之后被执行!...........
around 调用方法之后...
进行抛出异常的adivce展示-==================
15:05:05,671 DEBUG ThrowsAdviceInterceptor:88 - Found exception handler method: public void com.itcast.advice.ThrowAdvice.afterThrowing(java.lang.reflect.Method,java.lang.Object[],java.lang.Object,java.lang.Throwable)
around 调用方法之前....
beforeAdvice 调用方法之前被执行!...........
我在HelloSpeaker1中---hiBBB[测试抛出异常的advice]
15:05:05,687 DEBUG ThrowsAdviceInterceptor:119 - Found handler for exception of type [java.lang.Throwable]: public void com.itcast.advice.ThrowAdvice.afterThrowing(java.lang.reflect.Method,java.lang.Object[],java.lang.Object,java.lang.Throwable)
ThrowAdvice 记录异常...........
?
?