내부 메서드 호출에 대해서도 프록시 적용을 위해 setter를 통한 자기 자신 주입을 적용하려는데 아래와 같은 에러 메시지가 발생했습니다.
스프링 부트 2.6.X부터는 기본적으로 순환 참조를 금지하도록 변경되었습니다.
GitHub - spring-projects/spring-boot: Spring Boot
Spring Boot. Contribute to spring-projects/spring-boot development by creating an account on GitHub.
github.com
application.properties 혹은 application.yml에 아래와 같이 설정해주면 순환 참조가 허용됩니다.
강의는 스프링 2.5버전대지만 현재 스프링 이니셜라이저에서 기본 지정 버전은 2.6버전입니다.
여기서는 CallServiceV1에서 사용한 setter에 @Autowired 붙이는 문법을 사용 할 시에는 생성자로 주입할 때랑 똑같이 순환참조냐고 묻는 오류가 발생하더라구요.
혹시나 싶어서 2.5.6으로 해보니 잘 되더랍니다...ㅠㅠ
갑자기 2.6.0버전부터 무슨 일이 생긴지는 모르겠지만 여기서는 안되네요 ㅠㅠ
1, Preface
SpringBoot 2.6.x does not recommend the use of circular dependency, which is good news. Springboot gradually guides developers to write standard code from the bottom. At the same time, it is also sad news. The application scenarios of circular dependency are too wide.
If you upgrade from a lower version to 2.6 x. Then the first problem encountered by a large probability is the circular dependency problem.
2, Problem recovery
1. Code descriptionThe following styles of code are common: both classes have the need to call each other's methods, so it is easy to write circular references.
@Service public class TbDeptServiceImpl extends ServiceImpl<TbDeptMapper, TbDept> implements ITbDeptService { @Autowired private ITbStaffService staffService; }
@Service public class TbStaffServiceImpl extends ServiceImpl<TbStaffMapper, TbStaff> implements ITbStaffService { @Autowired private ITbDeptService deptService; }2. Error example
Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
Despite circular references being allowed, the dependency cycle between beans could not be broken. Update your application to remove the dependency cycle.
3, Problem solving
1. Rough settlementThe simplest way is to allow circular reference in the global configuration file. The default value of this property is false, and the display declaration is true, which can avoid the console circular reference exception when the project is started.
spring: main: allow-circular-references: true2. Elegant solution
Spring officially prohibits the use of circular dependencies by default, although there are optional configurations that allow developers to continue to use circular dependencies.
Spring's official intention is that it doesn't want developers to write code with circular dependency. That is to say, it may be forced not to use circular dependency in a future version. Therefore, we have to face the problem of gradually eliminating circular dependency in new projects.
Use the return value of the method to obtain the instance object, and replace the instance object injected through the member variable.
@Service public class TbDeptServiceImpl extends ServiceImpl<TbDeptMapper, TbDept> implements ITbDeptService { /** * Use the method to return the instance object and replace the member variable injection * @return ITbStaffService */ public ITbStaffService getStaffService(){ return SpringUtils.getBean(ITbStaffService.class); } }
@Service public class TbStaffServiceImpl extends ServiceImpl<TbStaffMapper, TbStaff> implements ITbStaffService { /** * Use the method to return the instance object and replace the member variable injection * @return ITbStaffService */ public ITbDeptService getDeptService(){ return SpringUtils.getBean(ITbDeptService.class); } }
The following dependencies need to be used. This dependency is a public dependency extracted by the author and can be used across projects.
<dependency> <groupId>xin.altitude.cms.common</groupId> <artifactId>ucode-cms-common</artifactId> <version>1.3.4</version> </dependency>
If this dependency cannot be found, it is likely that Alibaba cloud Maven warehouse has not been synchronized yet. It is enough to force the use of Maven central warehouse in the project.
<repositories> <repository> <id>public</id> <name>maven nexus</name> <url>//repo1.maven.org/maven2/</url> <snapshots> <updatePolicy>always</updatePolicy> </snapshots> </repository> </repositories>
4, Summary
As a widely used framework, Spring ecology has become the mainstream standard of Java enterprise applications. Its small changes have an immeasurable impact on the integration ecology. From follower to guide, we resolutely prohibit the problem of circular dependence, which reflects the responsibility as a guide.
I'm used to using circular references. It seems that the code is OK at first. It's unreasonable to think about it carefully. The direct expression of circular dependency is that you have me and I have you, which is puzzling from the design of objects.
Most developers always pay attention to the changes of the underlying framework, which will benefit in the application layer. The underlying framework mentioned here refers to JDK, Spring ecology, Apache, well-known big manufacturers' open source and widely used frameworks, such as guava.