背景
两个代码分支A、B,AB单独都能正常启动。
其中B分支进行了日志相关的改造,其中有一个点改动是 <aop:aspectj-autoproxy proxy-target-class=“true” />,限制了代理生成方式只能是cglib。
其中A分支是正常的业务开发,没有进行代理相关的改动。
当A分支merge到B分支时,启动发生异常:
[ERROR][2020/08/27 09:06:31.048][RMI TCP Connection(3)-127.0.0.1][sequenceid:] Context initialization failed [org.springframework.web.context.ContextLoader]java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy94
at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:446)
at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
Wrapped by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy94]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy94
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:212)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:109)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:447)
Wrapped by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dwsbfRcgzsbTzmxRepository': Post-processing of FactoryBean's singleton object failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy94]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy94
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:116)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1514)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:250)
问题分析
从打印的异常堆栈看,它的意思是无法继承final的类,无法创建dwsbfRcgzsbTzmxRepository。
首先可以理解的是,interface接口是final修饰的,因为接口是无法被继承的。而B分支做了 <aop:aspectj-autoproxy proxy-target-class=“true” />修改,创建代理只能通过继承实现,所以报错了。
可是,这个repository接口为什么需要创建代理呢?
问题发现
原来同事在接口方法上加了@Transactional注解,我们知道,spring 的事务是通过aop实现的,需要创建代理,而<aop:aspectj-autoproxy proxy-target-class=“true” />限制了只能通过cglib创建代理,所以就报错了。而在A分支没有报错的原因就是因为这里可以采用JDK动态代理实现,是没有问题的
问题解决
将 @Transactional注解移到service层,改为对service实体类创建cglib代理就通过了。