使用spring的AOP的动态代理报了这样的错误:
2015-11-13 11:25:28 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [testAspect.xml]
2015-11-13 11:25:31 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1e152c5: defining beans [org.springframework.aop.config.internalAutoProxyCreator,org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#0,aspectBean,aService,bService]; root of factory hierarchy
Exception in thread "main" -----------------
java.lang.ClassCastException: $Proxy11 cannot be cast to com.spring.service.BServiceImpl
at com.spring.main.TestAspectMain.main(TestAspectMain.java:18)
代码贴出来:
目标类
package com.spring.service;
// 使用cglib
public class BServiceImpl {
public void barB(String _msg, int _type) {
System.out.println("BServiceImpl.barB(msg:" + _msg + " type:" + _type
+ ")");
if (_type == 1)
throw new IllegalArgumentException("测试异常");
}
public void fooB() {
System.out.println("BServiceImpl.fooB()");
}
}
代理类
package com.spring.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
//这个类到底使用的是jdk的动态代理,还是<span style="font-family: Arial; font-size: 14px; line-height: 26px; text-indent: 28px;">CGLIB代理,搞不清楚</span>
@Aspect
public class TestAnnotationAspect {
@Pointcut("execution(* com.spring.service.*.*(..))")
private void pointCutMethod() {
System.out.println("vvvvvvvvv");
}
// 声明前置通知
@Before("pointCutMethod()")
public void doBefore() {
System.out.println("前置通知");
}
// 声明后置通知
@AfterReturning(pointcut = "pointCutMethod()", returning = "result")
public void doAfterReturning(String result) {
System.out.println("后置通知");
System.out.println("---" + result + "---");
}
// 声明例外通知
@AfterThrowing(pointcut = "pointCutMethod()", throwing = "e")
public void doAfterThrowing(Exception e) {
System.out.println("例外通知");
System.out.println(e.getMessage());
}
// 声明最终通知
@After("pointCutMethod()")
public void doAfter() {
System.out.println("最终通知");
}
// 声明环绕通知
@Around("pointCutMethod()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("进入方法---环绕通知");
Object o = pjp.proceed();
System.out.println("退出方法---环绕通知");
return o;
}
}
测试类
package com.spring.main;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.spring.service.BServiceImpl;
public class TestAspectMain {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext(
"testAspect.xml");
/*
* AService as = (AService) ac.getBean("aService"); as.fooA("dddd");
*/
// as.barA();
System.out.println("-----------------");
BServiceImpl ab = (BServiceImpl) ac.getBean("bService");
// ab.fooB();
ab.barB("ccccccc", 2);
}
}
配置文件
<?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"
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-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<!-- <aop:config>
<aop:aspect id="TestAspect" ref="aspectBean">-->
<!--配置com.spring.service包下所有类或接口的所有方法-->
<!-- <aop:pointcut id="businessService" expression="execution(* com.spring.service.*.*(..))" />
<aop:before pointcut-ref="businessService" method="doBefore"/>
<aop:after pointcut-ref="businessService" method="doAfter"/>
<aop:around pointcut-ref="businessService" method="doAround"/>
<aop:after-throwing pointcut-ref="businessService" method="doThrowing" throwing="ex"/>
</aop:aspect>
</aop:config>-->
<!-- <bean id="aspectBean" class="com.spring.aop.TestAspect" />
<bean id="aService" class="com.spring.service.AServiceImpl"></bean>
<bean id="bService" class="com.spring.service.BServiceImpl"></bean>-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 虽然看起来这个bean没用,但是必须配置,否则代理不了 -->
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"/>
<bean id="aspectBean" class="com.spring.aop.TestAnnotationAspect" />
<bean id="aService" class="com.spring.service.AServiceImpl"></bean>
<bean id="bService" class="com.spring.service.BServiceImpl"></bean>
</beans>
首先调用的时候直接拿的不是接口,BServiceImpl没有实现任何接口,
解决方法有两个:
第一、去掉配置文件中的
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
第二、将<aop:aspectj-autoproxy></aop:aspectj-autoproxy>换成<aop:config proxy-target-class="true"></aop:config> 这个表示使用CGLib动态代理技术织入增强