• 基于注解的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];
    }

    }

  • 相关阅读:
    随笔javascript/html5裁剪初试
    javascript开发随笔1,preventDefault的必要
    uploadify/swfupload HTTP_ERROR 406、302
    Python中__init__方法注意点
    ehcache.xsd No grammar constraints (DTD or XML Schema).
    Eclipse Organize Import 批量导包
    eclipse thymeleaf 插件安装
    windows 下 查看某个端口是否已经使用
    找符号网
    杀毒软件
  • 原文地址:https://www.cnblogs.com/zjuzcj/p/3653029.html
Copyright © 2020-2023  润新知