问题描述:
在使用spring boot框架实现事务控制demo时,启动项目报错如下:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'queryTypeController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.zeber.service.QueryTypeService com.zeber.controller.admin.QueryTypeController.queryTypeService; nested exception is java.lang.IllegalArgumentException: Can not set com.zeber.service.QueryTypeService field com.zeber.controller.admin.QueryTypeController.queryTypeService to com.sun.proxy.$Proxy101
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1202)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.context.web.SpringBootServletInitializer.run(SpringBootServletInitializer.java:117)
at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:108)
at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:68)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
原因:
后来一步步排查发现,只要在实现事务管理的service层类上加入@transactional注解,启动就会报上面的错,不加则没事。网上Google和stack overflow上找了好久,最后尝试把事务注解加在类的接口上,结果就好了。
查看官方案例,Spring Boot 使用事务非常简单,首先使用注解 @EnableTransactionManagement 开启事务支持后,然后在访问数据库的Service方法上添加注解 @Transactional ,在Service中,被 @Transactional 注解的方法,将支持事务;如果注解在类上,则整个类的所有方法都默认支持事务。
关于事务管理器,不管是JPA还是JDBC等都实现自接口 PlatformTransactionManager 如果你添加的是 spring-boot-starter-jdbc 依赖,框架会默认注入 DataSourceTransactionManager 实例。如果你添加的是 spring-boot-starter-data-jpa 依赖,框架会默认注入 JpaTransactionManager 实例。正是这些SpringBoot为我们自动做了,所以相对于我们并不透明,我现在依旧不是很明白为什么必须加在接口上,是不是和Spring Boot默认的注解注入有冲突,还是什么原因?
解决方案:
目前可行的是将注解通过接口的方式注入,然后就是在有多个事务管理器时,使用value具体指定使用哪个事务管理器@Transactional(value="txManager1")。
扩展话题
在找这个异常时,看到了这样一封关于Spring Boot接口使用的邮件回复,内容如下图:
更多推荐
Spring Boot异常:BeanCreationException:Injection of autowired dependencies failed;
发布评论