注:內有單詞(sping)寫錯,請忽略,不影響程序運行
運行時報錯:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mhl' defined in class path resource [myjava/wicherspingaop-aop.xml]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.aspectj.AspectJPointcutAdvisor#2': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.aop.aspectj.AspectJPointcutAdvisor]:
Constructor threw exception; nested exception is java.lang.IllegalArgumentException: warning no match for this type name: res [Xlint:invalidAbsoluteTypeName] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:479) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83) at myjava.Main.main(Main.java:9)
代碼如下:
Main.java
package myjava; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args){ //獲取IOC容器 ApplicationContext context = new ClassPathXmlApplicationContext("myjava/wicherspingaop-aop.xml"); Itest_1 mhl = context.getBean("mhl", Itest_1.class) ; // mhl.sayHello(); mhl.saveToDB("zzzzz") ; } }
Itest_1.java
package myjava; public interface Itest_1 { void sayHello() ; String saveToDB(String mData) ; }
test_1.java
package myjava; public class test_1 implements Itest_1 { private String name ; public test_1(){ } public test_1(String name){ this.name = name ; } public void setName(String name){ this.name = name ; } public void sayHello(){ System.out.println("sayHello " + name); } public String saveToDB(String mData){ System.out.println("SaveToDB: " + mData); return "tt" ; } }
mylog.java
package myjava; import org.aspectj.lang.ProceedingJoinPoint; public class mylog { // 1 - error; 2 - warn ; 3 - debug; 4 - info ; private int loglvl = 3 ; public void info(String mlog){ if (loglvl == 4){ System.out.println("Info:" + mlog); } } public void debug(String mlog){ if (loglvl >= 3) { System.out.println("debug:" + mlog); } } public void warn(String mlog){ if (loglvl >= 2) { System.out.println("warn:" + mlog); } } public void error(String mlog){ if (loglvl >= 1) { System.out.println("error:" + mlog); } } //前置通知 public void beforeAdvice(String messages){ System.out.println("前置通知, param:" + messages); } //后置返回通知 public void afterReturn(String res){ System.out.println("后置返回通知,返回值:" + res); //System.out.println("=============================="); } //后置異常通知 public void afterThrowing(Exception exception){ System.out.println("后置異常通知:" + exception); } //后置最終通知 public void afterFinally(String messages){ System.out.println("后置最終通知:" + messages); } //環繞通知 public String aroundAdvice(ProceedingJoinPoint joinPoint, String messages) throws Throwable{ try { System.out.println("環繞通知,接入點:" + joinPoint + ",原param:" + messages); System.out.println("放行目標方法並改變參數,將執行結果返回"); String res = (String) joinPoint.proceed(new Object[] {"param has been replaced "}); System.out.println("環繞通知改變了返回結果"); res = res.concat("& res has been changed"); System.out.println("返回結果為:"+res); return res; }catch (Exception e){ e.printStackTrace(); } return null; } }
wicherspingaop-aop.xml
<?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd" > <bean id = "mhl" class="myjava.test_1"> <property name="name" value="Wicher"></property> </bean> <bean id = "log" class="myjava.mylog"></bean> <!--頂層的AOP配置元素,大多數的<aop:*>包含在<aop:config>元素內--> <aop:config> <!--定義外部切入點,該切入點可以被多個切面使用--> <aop:pointcut id="pointcut_log" expression="execution(* myjava.test_1.* (..)) and args(messages)"/> <!--定義切面--> <aop:aspect ref="log"> <!--定義內部切入點,該切入點只能被當前切面使用--> <!--<aop:pointcut id="pointcut_log_inner" expression="execution(* myjava.test_1.* (..)) and args(messages)"/>--> <!--前置通知--> <aop:before method="beforeAdvice" arg-names="messages" pointcut-ref="pointcut_log"/> <!--后置通知 不管該方法是否執行成功--> <aop:after method="afterFinally" arg-names="messages" pointcut="execution(* myjava.test_1.* (..)) and args(messages)"/> <!--后置返回通知 在方法成功執行后調用通知--> <!--<aop:after-returning method="afterReturn" arg-names="res" returning="res" pointcut="execution(* myjava.test_1.* (..))"/>--> <aop:after-returning method="afterReturn" arg-names="res" returning="res" pointcut="execution(* myjava.test_1.* (..)) and args(res)"/> <!--后置異常通知 在方法拋出異常后調用通知--> <aop:after-throwing method="afterThrowing" arg-names="exception" pointcut="execution(* myjava.test_1.* (..)) and args(exception)"/> <!--環繞通知--> <aop:around method="aroundAdvice" arg-names="joinPoint,messages" pointcut="execution(* myjava.test_1.* (..)) and args(messages)"/> </aop:aspect> </aop:config> </beans>
工程路徑
從網上down的demo能正常運行,自己先排錯,把xml中環繞通知隱藏,運行正常,依次把前置通知(before),后置通知(after)取消隱藏,運行正常,再將after-returning取消隱藏時錯,仔細與demo對比,發現在aop:after-returning的屬性pointcut中是沒有and args(res)的,去掉后運行正常, 因為對aop配置文件還不太熟,原因還不知道,后續確定原因后再記錄。
全部lib文件如下(com.springsource.org.aspectj.weaver-1.6.4.RELEASE.jar是手工下載的,其他都是在建立spring時勾選的download自動下載):
后置通知