<?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