使用@EnableTransactionManagement报错

记录一下报错:

今天想做事务控制,在启动器类上加了**@EnableTransactionManagemen**t来开启事务,并在service层方法上加上了 @Transactional(rollbackFor = Exception.class),如何启动启动器类,就报如下错误了,第一次碰到
版本:

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

在这里插入图片描述

2023-03-16 15:13:56.330  WARN 1244 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'excelDemo': Unsatisfied dependency expressed through field 'resoucefileService'; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'resoucefileServiceImpl' is expected to be of type 'com.example.demo.service.impl.ResoucefileServiceImpl' but was actually of type 'com.sun.proxy.$Proxy96'
2023-03-16 15:13:56.333  INFO 1244 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2023-03-16 15:13:56.343  INFO 1244 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2023-03-16 15:13:56.346 ERROR 1244 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

The bean 'resoucefileServiceImpl' could not be injected as a 'com.example.demo.service.impl.ResoucefileServiceImpl' because it is a JDK dynamic proxy that implements:
	com.example.demo.service.IResoucefileService


Action:

Consider injecting the bean as one of its interfaces or forcing the use of CGLib-based proxies by setting proxyTargetClass=true on @EnableAsync and/or @EnableCaching.


Process finished with exit code 1

翻译一下:

上下文初始化期间遇到异常 -
取消刷新尝试:org.springframework.beans.factory.UnsatisfiedDependency异常:创建名为“excelDemo”的Bean时出错:通过字段“resoucefileService”表示的不满意依赖项;嵌套异常是org.springframework.beans.factory.BeanNotOfRequiredTypeException:名为“resoucefileServiceImpl”的Bean应该属于“com.example.demo.service.impl.ResoucefileServiceImpl”类型,但实际上“com.sun.proxy.$Proxy 96”类型。

描述:
bean ‘resoucefileServiceImpl’ 无法作为’com.example.demo.service.impl.ResoucefileServiceImpl’ 注入,因为它是一个 JDK动态代理,它实现了: com.example.demo.service.IResoucefileService

行动:

考虑将 Bean 注入为其接口之一,或者通过在@EnableAsync和/或@EnableCaching上设置
proxyTargetClass=true 来强制使用基于 CGLib 的代理。

解决方法(强制使用CGLIB的代理)
(一)在这里插入图片描述
(二)
在这里插入图片描述

解决方法(使用接口注入)

原因分析

我用的是@Transaction注解,底层是基于jdk的代理方式
在这里插入图片描述
jdk代理需要使用接口,而我用的实现类,所以报错了

这样就会产生冲突,所以需要强制Springboot使用cglib的代理方式来生成。

@Transaction使用JDK动态代理,‌而Springboot默认使用cglib动态代理。‌

JDK动态代理:‌这是Java提供的一种动态代理机制,‌它利用反射机制生成一个实现代理接口的匿名类,‌在调用具体方法前通过调用InvocationHandler来处理。‌这种代理方式要求目标对象必须实现一个接口,‌因此,‌如果目标对象实现了接口,‌Spring框架会默认采用JDK的动态代理实现AOP(‌面向切面编程)‌。‌

cglib动态代理:‌与JDK动态代理不同,‌cglib利用asm开源包对代理对象类的class文件进行加载,‌通过修改其字节码生成子类来处理。‌这种代理方式不需要目标对象实现接口,‌如果目标对象没有实现接口,‌必须采用CGLIB库。‌Spring框架会在JDK动态代理和CGLIB之间自动转换,‌当目标对象没有实现接口时,‌Spring会自动选择使用CGLIB进行代理。‌

在Spring框架中,‌@Transaction注解通常用于声明事务边界,‌由于它依赖于接口定义的方法来进行事务管理,‌因此更适合使用JDK动态代理。‌而Springboot作为Spring框架的扩展,‌虽然默认情况下可能会根据目标对象是否实现接口来选择使用JDK动态代理或CGLIB动态代理,‌但在某些情况下,‌比如当目标对象没有实现接口时,‌Springboot会默认使用cglib动态代理来确保AOP的正常工作

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值