注:内有单词(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自动下载):
后置通知