springboot是集成了springweb环境的集成开发环境。可以让我们不用再配置许多spring包,只要执行springboot的包地址,springboot就能够将对应的包引入到项目中来。
springboot能够做到0xml配置,环境变量都可以通过boot的相应插件进行配置。
我手里面有一个项目,想通过springboot重新组织一下。从月初动手到现在算是对springboot有一个简单的了解。本文就将通过我的集成过程遇到的问题来说明一个侧面。我主要就是要阐述springboot在我项目启动过程中遇到的问题。至于springboot的过程学习,我认为看官网的内容就好。
https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples
在我的项目中用了大量的泛型。期初整合springboot 的时候有很多的错误报出来,首先的一个就是
1、Caused by: java.lang.VerifyError: (class: com/framework/demo/dao/impl/showcaseSample/ShowcaseSampleDaoImpl$$EnhancerBySpringCGLIB$$953299fc, method: CGLIB$saveSelective$9 signature: (Ljava/lang/Object;)V) Incompatible argument to function
2、 Unexpected AOP exception; nested exception is java.lang.IllegalStateException: Unable to load cache item
第一个问题一看就是ShowcaseSampleDaoImpl被cglib代理过程中报错了。当时并不明白什么原因所以自己写了一个test模拟.
@Test
public void cglibProxyDaoClass(){
PersistenceExceptionTranslationAdvisor persistenceExceptionTranslationAdvisor = new PersistenceExceptionTranslationAdvisor(new MyBatisExceptionTranslator(new DruidDataSource(),false), Repository.class);
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(new PersonalCalendarDaoImpl());
proxyFactory.addAdvisor(persistenceExceptionTranslationAdvisor);
Object o = proxyFactory.getProxy();
}
发现确实用cglib代理会报这个错。再看这个错写着:不兼容的参数。大概猜到cglib代理过程中某些参数类型未找到。想想应该是cglib代理的过程中生成了ShowcaseSampleDaoImpl的子类,而这个子类没有让父类指定类型,所以会出现泛型参数无法匹配的情况。我换用了jdk做代理发现这个问题解决了。
跟踪代码发现,这个dao类之所以被aop拦截是因为配置了事务,事务中的这个类 PersistenceExceptionTranslationPostProcessor代理的类型指定了cglib。于是我从新配置了这个类,改成jdk类型代理.
1、启动类将该配置去除。
@SpringBootApplication(exclude = PersistenceExceptionTranslationAutoConfiguration.class)
@EnableConfigurationProperties
public class MyApplication extends SpringBootServletInitializer {
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MyApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
2、重新配置该类
@Configuration
public class PersistenceExceptionTranslationAutoConfiguration {
@Bean
@ConditionalOnMissingBean(PersistenceExceptionTranslationPostProcessor.class)
@ConditionalOnProperty(prefix = "spring.dao.exceptiontranslation", name = "enabled", matchIfMissing = true)
public static PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor() {
PersistenceExceptionTranslationPostProcessor postProcessor = new PersistenceExceptionTranslationPostProcessor();
postProcessor.setProxyTargetClass(false);
return postProcessor;
}
}
查api文档发现如果想将某个类代理自己指定也可以用标签:
@Scope(value= WebApplicationContext.SCOPE_REQUEST,proxyMode= ScopedProxyMode.INTERFACES)
欢迎公众微信号:hyssop的后花园