代码编织梦想

首先我有一个Class A和Class B,A和B存在循环依赖。

@Service
@Transactional(rollbackFor = Exception.class)
public class A implements Ainterface{

	@Autowired
	private B b;

	@Override
	public void methodA() {
	 // do something...
	}
}

@Service
public class B implements BInterface{

	@Autowired
	private A a;

	@Override
	public void methodB() {
		a.methodA();
	}
}

一般情况下,也就是不加Transactional注解是没有问题的,因为我们的spring框架默认就支持循环依赖,但是我们这个例子在Class A上加了个注解,为什么会有循环依赖的报错呢,报错信息如下:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘b’: Unsatisfied dependency expressed through field ‘a’; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named ‘a’ is expected to be of type ‘com.qhyu.cloud.circlarRefrence.A’ but was actually of type ‘com.sun.proxy.$Proxy32’

该异常信息表明在创建名为 ‘b’ 的Bean时,其依赖的 ‘a’ 字段无法满足依赖关系,因为Spring无法将 ‘a’ 注入到 ‘b’ 中的 ‘a’ 字段上。

异常信息中还提到了一个嵌套异常,即 ‘BeanNotOfRequiredTypeException’,它表明 Spring 无法将名为 ‘a’ 的Bean注入到 ‘b’ 中的 ‘a’ 字段上,因为 ‘a’ Bean的类型与 ‘b’ 中 ‘a’ 字段的类型不匹配。具体来说, ‘a’ Bean的实际类型是 ‘com.sun.proxy.$Proxy32’,而 ‘b’ 中的 ‘a’ 字段的期望类型是 ‘com.qhyu.cloud.circlarRefrence.A’。

通过这个异常信息,我们很快就找到了思路,初步估计问题是发生在populateBean方法,在属性注入的时候会验证属性类型,因为我们的Service都是实现了接口的,所以在没有强制使用cglb进行代理的情况下,会使用jdk动态代理,当存在代理对象时,如果使用JDK动态代理,代理对象会实现目标接口并继承Proxy类,而不是原始类,因此在填充代理对象的属性时,Spring无法确定该使用哪一个对象进行属性填充,因此无法正确地替换代理对象。这种情况下,可以考虑使用CGLIB动态代理来解决该问题。

源码中校验的位置在DefaultListableBeanFactory的1401行,报错信息在1402行抛出。
在这里插入图片描述

要解决这个问题,可以采用以下方法:

1、解决循环依赖:尽量避免类之间的循环依赖,可以通过将共享的方法或数据移动到一个新的类中,然后让两个类分别依赖这个新类。

2、使用setter注入:如果无法避免循环依赖,可以考虑使用setter方法进行依赖注入,而不是构造方法注入。这样,当一个类被实例化时,它的依赖关系会在实例化之后才被注入,可以避免代理对象替换的问题。

3、指定代理类型:可以明确指定代理类型。例如,可以使用@EnableTransactionManagement(proxyTargetClass = true)来强制使用基于类的代理(CGLIB代理),而不是默认的基于接口的代理(JDK动态代理)。这样,循环依赖解析过程中,代理对象会被正确地替换。或者将@Transactional 注解移动到方法上。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Tanganling/article/details/129667139

spring ioc源码简析-爱代码爱编程

1. ClassPathXmlApplicationContext 首先我们先从平时启动spring常用的ClassPathXmlApplicationContext开始解析 ApplicationContext con

Spring 进阶-爱代码爱编程

Spring 进阶 官网文档 一. Spring 简介 Spring 技术点: Core: IoC Container, Events, Resources, i18n, Validation, Data Binding, Type Conversion, SpEL, AOP. Spring IOC 应该添加的依赖包 <

Spring笔记-爱代码爱编程

Spring 框架 高度抽取的可重用代码的一种设计,高度的通用性(缺乏业务逻辑代码的半成品的项目) Spring优良特性 1、非侵入式:基于spring开发的应用中的对象可以不依赖与Sprig的API 2、依赖注入:DI(Dependency Injection)反转控制(IOC)最经典的实现 3、面向切面编程:AOP(Aspec

Spring事务的那些坑,这里都给你总结好了!-爱代码爱编程

目录 一、Spring事务管理的几种方式: 1.  声明式 2.  编程式 二、Spring事务实现机制 三、Spring事务的那些坑 3.1 事务不生效 3.2 事务不回滚 3.3 事务超时不生效 四、 总结 1.  Spring事务未生效 2.  Spring事务回滚失效 3.  Spring事务超时不准确或失效 Spring

Spring 事务的那些坑,都在这里了!-爱代码爱编程

作者:蚊子squirrel来源:www.jianshu.com/p/a4229aa79ace Spring框架已是JAVA项目的标配,其中Spring事务管理也是最常用的一个功能,但如果不了解其实现原理,使用姿势不对,一不小心就可能掉坑里。 为了更透彻的说明这些坑,本文分四部分展开阐述: 第一部分简单介绍下Spring事务集成的几种方式; 第

Spring事务的那些坑-爱代码爱编程

转载来自 作者:蚊子squirrel原文地址 Spring框架已是JAVA项目的标配,其中Spring事务管理也是最常用的一个功能,但如果不了解其实现原理,使用姿势不对,一不小心就可能掉坑里。为了更透彻的说明这些坑,本文分四部分展开阐述:第一部分简单介绍下Spring事务集成的几种方式;第二部分结合Spring源代码说明Spring事务的实现原理;第三部分

【转载】Spring事务的那些坑,这里都给你总结好了!-爱代码爱编程

【转载】Spring事务的那些坑,这里都给你总结好了! 作者:蚊子squirrelwww.jianshu.com/p/a4229aa79ace Spring框架已是JAVA项目的标配,其中Spring事务管理也是最常用的一个功能,但如果不了解其实现原理,使用姿势不对,一不小心就可能掉坑里。 为了更透彻的说明这些坑,本文分四部分展开阐述:第一部分简单介绍

Spring-爱代码爱编程

Spring 1. Spring简介 spring的模块划分 ​ Test:spring的单元测试模块Core Container:核心容器(IOC)黑色代表这部分的功能由哪些jar包组成,要使用这个部分的完整功能,就不要导入这些jar包AOP + Aspects:面向切面编程模块Data Access:访问数据库的模块Web:web应用模块

常见面试题总结-爱代码爱编程

01 怎么样封装简历 写技能,至少有一两项是精通的,不要全是熟悉这样泛泛而谈想投一个公司,根据想投公司的岗位要求,把自己的简历对着改02 hashmap底层执行原理 hashmap的存储结构 数组、链表、红黑树特点 1.快速存储2.快速查找,时间复杂度是O(1)3.可伸缩,数组可以扩容,链表长度超过8以后会变成红黑树hashmap底层执行原理–ha

Spring源码整体分析-爱代码爱编程

spring 架构原理图 核心注解 常用注解 @Bean 使用 @Bean + @Configuration 的形式可以替代 xml 配置文件的形式 @Import @Import:指示要导入的一个或多个组件类 Spring 提供了很多方式来定义 bean 的信息,包括 xml 配置文件,注解,网络,磁盘等,通过资源加载器加载这些

SpringBoot 启动流程-爱代码爱编程

SpringBoot 启动流程 1. 启动入口2. 创建 SpringApplication3. 运行 Spring 应用程序3.1 创建应用上下文3.2 刷新应用上下文3.2.1 解析配置文件、生成所有的 beanDefinitions3.2.1.1 什么是BeanDefinition?3.2.1.2 invokeBeanFactoryPostP

SpringDataJPA+Hibernate框架源码剖析(六)@PersistenceContext和@Autowired注入EntityManager的区别-爱代码爱编程

SpringDataJPA+Hibernate框架源码剖析系列文章: SpringDataJPA+Hibernate框架源码剖析(一)框架介绍SpringDataJPA+Hibernate框架源码剖析(二)框架整合 之 EntityManagerFactory的构建SpringDataJPA+Hibernate框架源码剖析(三)框架整合 之 Reposi

开发技术-java实体类链式赋值简单示例-爱代码爱编程

文章目录 1. 普通的赋值方式2. 使用 @Builder3. 使用@Accessors 1. 普通的赋值方式 这是个非常普通的实体类 public class User { private Str

【spring高级49讲】-爱代码爱编程

Spring高级49讲 Spring是整个Java体系最核心的框架,没有之一面试必备技术、思想提升 一.容器和Bean 第1讲.BeanFactory和ApplicationContext 1.1.Bean

jpa更新部分字段方式-爱代码爱编程

JPA相较于Mybatis来说,对于增、删、查功能倒是相差不大,但是就更改这一块,个人感觉还是mybatis方便一些,因此这里总结下自己的JPA更新字段的方式。 JPA更新最大的问题是没有可以直接使用的函数,目前只能依托于

实验5---spring ioc-注解实现-爱代码爱编程

Spring IoC-注解实现 一、实验目的及任务 通过该实验掌握利用Spring 注解方式实现控制反转IoC(依赖注入),掌握Spring常用注解的含义和用法。 二、实验结果 自己编写的代码和配置信息,包括applicationContext.xml,UserServiceImpl,UserDaoImpl等与注解相关的代码。

springboot集成quartz实现定时任务(可修改cron表达式和传入参数)-爱代码爱编程

第一步创建SpringBoot项目的过程我就不在演示了!自己找找教程吧! 第二步,导入依赖: <dependencies> <dependency> <groupId>org.springframework.boot</groupId> &

springcloud五大核心组件-爱代码爱编程

Consul 等,提供了搭建分布式系统及微服务常用的工具,如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性token、全局锁、选主、分布式会话和集群状态等,满足了构建微服务所需的所有解决方案。 服务发现——Netflix Eureka 客服端负载均衡——Netflix Ribbon 断路器——Netflix Hystrix 服务网关

基于java下springboot框架实现小区物业管理系统_编写小区物业管理系统用到的语言和框架-爱代码爱编程

基于java下Springboot框架实现小区物业管理系统 开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.9 关键字:小区物业管理