关键词
JavaEE JavaWeb eclipse XML AspectJ
描述
1.报错记录。摸索中。轻喷。
2.《Java EE框架整合开发入门到实战:Spring+Spring MVC+MyBatis(微课版)》4.4节“基于XML配置开发AspectJ”
报错
警告: Exception encountered during context initialization – cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘testDao’ defined in class path resource [aspectj/xml/applicationContext.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#1’: Cannot create inner bean ‘(inner bean)#57175e74’ of type [org.springframework.aop.aspectj.AspectJAfterReturningAdvice] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘(inner bean)#57175e74’: Cannot create inner bean ‘(inner bean)#7bb58ca3’ of type [org.springframework.aop.config.MethodLocatingFactoryBean] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘(inner bean)#7bb58ca3’: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Unable to locate method [afterReturning] on bean [myAspect]
检查
拖到最右边查看报错
Unable to locate method [afterReturning] on bean [myAspect]
就是说bean实例myAspect中的方法afterReturning有问题。
检查MyAspect.java中的方法afterReturning。与applicationContext.xml对应位置进行比较。
发现是MyAspect.java中的方法afterReturning拼写有问题(多写了个n)。与applicationContext.xml对应不上。
解决
将MyAspect.java中的方法 afterReturnning 改为 afterReturning 。与applicationContext.xml中的 afterReturning 对应上。
总结
1.查看eclipse报错部分的最上面的最右边
2.检查xml文件以及报错提示的bean对应java文件。
(补充)项目
结构
package aspectj.xml;
applicationContext.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"> <!-- 定义目标对象,使用4.2.1节的实现类--> <bean id="testDao"/> <!-- 定义切面--> <bean id="myAspect"/> <!-- AOP配置 --> <aop:config> <!-- 配置切面 --> <aop:aspect ref="myAspect"> <!-- 配置切入点,通知增强哪些方法 --> <aop:pointcut expression="execution(* dynamic.jdk.*.*(..))" id="myPointCut"/> <!-- 将通知与切入点关联 --> <!-- 关联前置通知 --> <aop:before method="before" pointcut-ref="myPointCut" /> <!-- 关联后置返回通知,在目标方法成功执行后执行 --> <aop:after-returning method="afterReturning" pointcut-ref="myPointCut"/> <!-- 关联环绕通知--> <aop:around method="around" pointcut-ref="myPointCut"/> <!-- 关联异常通知,没有异常发生时将不会执行增强,throwing属性设置通知的第二个参数名称--> <aop:after-throwing method="except" pointcut-ref="myPointCut" throwing="e"/> <!-- 关联后置(最终)通知,不管目标方法是否成功都要执行--> <aop:after method="after" pointcut-ref="myPointCut"/> </aop:aspect> </aop:config> </beans>
MyAspect.java
package aspectj.xml; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; //切面类,在此类中编写各种类型的通知 public class MyAspect { //前置通知,使用JoinPoint接口作为参数获得目标对象信息 public void before(JoinPoint jp){ System.out.println("前置通知:模拟权限控制"); System.out.println(",目标类对象:"+jp.getTarget()+",被增强处理的方法:"+jp.getSignature().getName()); } //后置返回通知 public void afterReturnning(JoinPoint jp){ System.out.println("后置返回通知:"+"模拟删除临时文件"); System.out.println(",被增强处理的方法"+jp.getSignature().getName()); } /** * 环绕通知 * ProceedingJoinPoint是JoinPoint的子接口,代表可以执行的目标方法 * 返回值的类型必须是一个Object * 必须一个参数是ProceedingJoinPoint类型 * 必须throws Throwable * @param pjp * @return * @throws Throwable */ public Object around(ProceedingJoinPoint pjp) throws Throwable{ //开始 System.out.println("环绕开始:执行目标方法前,模拟开始事务"); //执行当前目标方法 Object obj = pjp.proceed(); //结束 System.out.println("环绕结束:执行目标方法后,模拟关闭事务"); return obj; } //异常通知 public void except(Throwable e){ System.out.println("异常通知:"+"程序执行异常"+e.getMessage()); } //后置(最终)通知 public void after(){ System.out.println("最终通知:模拟释放资源"); } }
XMLAspectJTest.java
package aspectj.xml; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import dynamic.jdk.TestDao; public class XMLAspectJTest { //在主方法中使用Spring容器获取代理对象,并执行目标方法 public static void main(String[] args) { ApplicationContext appCon = new ClassPathXmlApplicationContext("/aspectj/xml/applicationContext.xml"); //从容器中获取增强后的目标对象 TestDao testDaoAdvice = (TestDao)appCon.getBean("testDao"); //执行方法 testDaoAdvice.save(); /* 前置通知:模拟权限控制 ,目标类对象:dynamic.jdk.TestDaoImpl@45b9a632,被增强处理的方法:save 环绕开始:执行目标方法前,模拟开始事务 保存 最终通知:模拟释放资源 环绕结束:执行目标方法后,模拟关闭事务 后置返回通知:模拟删除临时文件 ,被增强处理的方法save */ } }
package dynamic.jdk;
TestDao.java
package dynamic.jdk; public interface TestDao { public void save(); public void modify(); public void delete(); }
TestDaoImpl.java
package dynamic.jdk; //该实现类作为目标类,在代理类中对实现类的方法进行增强处理 public class TestDaoImpl implements TestDao { @Override public void save() { System.out.println("保存"); } @Override public void modify() { System.out.println("修改"); } @Override public void delete() { System.out.println("删除"); } }
运行结果(运行XMLAspectJTest.java)