基於注解的Spring AOP攔截含有泛型的DAO


  • 出錯場景

1、抽象類BaseDao

public abstract class BaseDao<T> {

public BaseDao() {

entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

}

private Class<T> entityClass;

@Resource
private SessionFactory sessionFactory;
}

2、applicationContext.xml文件中配置:需要引入aop的命名空間和增加如下配置

<aop:aspectj-autoproxy proxy-target-class="true"/>

3、編寫自己的aop類

@Component
@Aspect
public class GlobalValueAspect {
@Pointcut(
"execution(* com.test.dao.SceneryDao.save*(..)) " +
"|| execution(* com.test.dao.SceneryDao.update*(..)) " +
"|| execution(* com.test.dao.SceneryDao.delete*(..))")
public void aspect(){}
@Before("aspect()")
public void before(JoinPoint joinPoint){
System.out.println("before");
}

@After("aspect()")
public void after(JoinPoint joinPoint){
System.out.println("after");
}
@Around("aspect()")
public void around(JoinPoint joinPoint){
System.out.println("around");
}
@AfterThrowing("aspect()")
public void afterThrowing(){
System.out.println("afterthrow");
}
@AfterReturning("aspect()")
public void afterReturn(JoinPoint joinPoint){
}
@Resource
private GlobalValueAspectDao globalValueAspectDao;
}

4、運行時會報一個錯誤

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sceneryDao' defined in file : Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.lztravel.dao.SceneryDao]: Common causes of this problem include using a final class or a non-visible class; nested exception is org.springframework.cglib.core.CodeGenerationException: java.lang.ClassCastException-->java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4206)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4705)
at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3461)
at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:426)
at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1361)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1653)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1662)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1662)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1642)
at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class : Common causes of this problem include using a final class or a non-visible class; nested exception is org.springframework.cglib.core.CodeGenerationException: java.lang.ClassCastException-->java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:211)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:111)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:477)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:362)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:409)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1488)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
... 21 more
Caused by: org.springframework.cglib.core.CodeGenerationException: java.lang.ClassCastException-->java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
at org.springframework.cglib.core.ReflectUtils.newInstance(ReflectUtils.java:235)
at org.springframework.cglib.core.ReflectUtils.newInstance(ReflectUtils.java:220)
at org.springframework.cglib.core.ReflectUtils.newInstance(ReflectUtils.java:216)
at org.springframework.cglib.proxy.Enhancer.createUsingReflection(Enhancer.java:643)
at org.springframework.cglib.proxy.Enhancer.firstInstance(Enhancer.java:538)
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:225)
at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:285)
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:205)
... 28 more

Caused by: java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
at com.test.dao.BaseDao.<init>(BaseDao.java:23)
at com.test.dao.SceneryDao.<init>(SceneryDao.java:13)

  • 原因分析

Spring AOP是通過代理實現的,代理類繼承了這里的SceneryDao,而SceneryDao繼承了抽象類BaseDao,所以對於aop代理類來說,執行BaseDao中下面這句代碼時出錯了。

entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

因為代理類的父類是SceneryDao,而SceneryDao不是一個泛型類型(ParameterizedType),所以出現強制類型轉換錯誤。

  • 解決方法:

在BaseDao的構造方法中增加一個判斷語句:if (getClass().getGenericSuperclass() instanceof ParameterizedType)。具體修改構造方法如下:

public BaseDao() {

if (getClass().getGenericSuperclass() instanceof ParameterizedType) {
entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
} else {
entityClass = (Class<T>) ((ParameterizedType) getClass().getSuperclass().getGenericSuperclass())
.getActualTypeArguments()[0];
}

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM