after my teammates merged her changes (implements @EnableFeignClients for our SpringBootApplication and created some feign clients, properties and configs from the main branch), when boot the application it will pop up the The dependencies of some of the beans in the application context from a cycle: xxx
To resolve this issue I deleted some @Autowired from some involved controller/service classes and make them private and then the application can be boot successfully:
before my change:
@Autowired
MyUtil myUtil; //@Component
@Autowired
MyConfig myConfig; //@Component
@Autowired
MyApi myApi; //Interface class
public void myFunction(){
String id = myUtil.getId();
String name = myConfig.getNameById(id);
myApi.sendInfo(id, name);
}
after my change:
private MyUtil myUtil; //@Component
private MyConfig myConfig; //@Component
private MyApi myApi; //@Component
public void myFunction(){
String id = myUtil.getId();
String name = myConfig.getNameById(id);
myApi.sendInfo(id, name);
}
Spring version:
<groupID>org.springframework.boot</groupID>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.11</version>
and here are my concerns:
Will there be any impact after my changes (functional, performance, etc.)?
In my case (or in most scenarios in the future development), should i use @Autowired? When need to? When doesn't need to?
CodePudding user response:
@Autowired help the spring to find where it should inject classes.
The impact is that spring will not create objects of the classes where you removed the annotation.
Additional way to create objects in spring are with setter or constructor injection.
Example of constructor injection will be something like:
public YourClassName(MyUtil myUtil, MyConfig myConfig, MyApi myApi){
this.myUtil = myUtil;
this.myConfig = myConfig;
this.myApi = myApi;
}
I think also good idea as well to check why @Autowired not working. Can you provide full error? Does your class annotated with @Service or something
CodePudding user response:
TL DR. You cannot delete @Autowired directly.
@Autowired is used by Spring in order to do dependency injection ( I know this is a fancy word)
@Autowired
ChickenService chickenService
@Autowired is almost equivalent to ChickenService chickenService = new ChickenService();
After your change,private MyConfig myConfig; //@Component
myConfig
will be null and therefore you introduced a bug.
Suppose that you have an EggService
@Service
public class ChickenService {
@Autowired
private EggService eggService;
}
The chicken holds a reference to the egg
@Service
public class EggService {
@Autowired
private ChickenService;
}
Now you have a chicken and egg problem. https://www.baeldung.com/circular-dependencies-in-spring