<?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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!-- AOP配置流程 一、配置被代理对象 二、前置通知 三、代理对象 --> <!-- 被代理对象 --> <bean id="testservice1" class="com.pas.service.TestService1"> <property name="name" value="ping" /> </bean> <bean id="testservice2" class="com.pas.service.TestService2"> <property name="name" value="ping" /> </bean> <!-- 前置通知 --> <bean id="beforeadvice" class="com.pas.notify.BeforeAdvice" /> <!-- 后置通知 --> <bean id="afteradvice" class="com.pas.notify.AfterAdvice" /> <!-- 环绕通知 --> <bean id="aroundadvice" class="com.pas.notify.AroundAdvice"/> <!-- 异常通知 --> <bean id="throwadvice" class="com.pas.notify.ThrowsAdvice"/> <!-- 引入通知 过滤通知中的某些切入点 --> <bean id="myBeforeAdviceFilter" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <!-- 针对的通知bean --> <property name="advice" ref="beforeadvice"/> <property name="mappedNames"> <!-- 只对如下方法名织入 --> <list> <!-- 名称也可使用正则过滤 --> <value>sayHello</value> </list> </property> </bean> <!-- 代理对象 --> <bean id="myproxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 代理接口集 --> <property name="proxyInterfaces"> <list> <value>com.pas.inter.TestServiceInter</value> <value>com.pas.inter.TestServiceInter2</value> </list> </property> <!-- 织入通知到代理对象 --> <property name="interceptorNames"> <list> <!-- 此处引用的是自定义的链接点过滤器id --> <value>myBeforeAdviceFilter</value> <value>afteradvice</value> <value>aroundadvice</value> <value>throwadvice</value> </list> </property> <!-- 配置被代理对象 --> <property name="target"> <!-- 通知只对被代理对象有效 --> <ref bean="testservice1" /> </property> </bean> </beans>
/* * 前置通知类 */ public class BeforeAdvice implements MethodBeforeAdvice { /* * method:被调用的方法 * args:method接收到的参数 * target:目标对象 */ @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("前置通知-写入日志"); } }
/* * 后置通知 */ public class AfterAdvice implements AfterReturningAdvice { @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("后置通知-事务提交"); } }
/* * 环绕通知 */ public class AroundAdvice implements MethodInterceptor { /* * 执行在函数体内,具体内容调用以前 * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation) */ @Override public Object invoke(MethodInvocation arg0) throws Throwable { // TODO Auto-generated method stub System.out.println("环绕通知-调用方法前"); Object o=arg0.proceed(); System.out.println("环绕通知-调用方法后"); return o; } }
/* * 异常通知 */ public class ThrowsAdvice implements org.springframework.aop.ThrowsAdvice { public void afterThrowing(Method m,Object[] os,Object target,Exception throwable) { System.out.println("异常通知-出事了"+throwable.getMessage()); } }
public class Test { public static void main(String[] args) { ApplicationContext ac = ApplicationContextUtil.getApplicationContext(); //取代理对象的id TestServiceInter2 t=(TestServiceInter2) ac.getBean("myproxy"); // ((TestServiceInter)t).sayHello(); // ((TestServiceInter)t).sayHi(); t.sayBye(); } }
console: java
sayHello: spring
前置通知-写入日志
环绕通知-调用方法前
Hello:TestService1
环绕通知-调用方法后
后置通知-事务提交 app
SayBye测试异常:
环绕通知-调用方法前
bye:ping
异常通知-出事了/ by zero
Exception in thread "main" java.lang.ArithmeticException: / by zero
…… ide