In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
What this article shares with you is the solution to the problem of SpringBean circular dependence. The editor thinks it is very practical, so I share it with you. I hope you can get something after reading this article. Without saying much, let's take a look at it with the editor.
What is the circular dependency of Spring? what is the circular dependency of Spring? What are the problems with circular dependency?
Example: AService depends on BService; BService depends on AService
@ Servicepublic class AService {/ @ Autowired public BService bService;} @ Servicepublic class BService {@ Autowired public AService aService;}
The problem of circular dependency in Spring in the case of a single case, Spring has solved it for us, but many cases have not solved the problem of circular dependency.
Why, in many cases, Spring does not solve the problem of circular dependency?
Because in the case of multiple cases, the setting of multiple instances of the object is not clear which one, there will be the problem of circular dependency.
Many examples of Spring We need to: how to solve the problem of circular dependency?
We can go by ourselves: clearly specify which object to reference.
@ Service@Scope ("prototype") public class AService {/ / @ Autowired public BService bService; / / Why did Bservice create public AService () {System.out.println ("AService is created by Java's reflection technology") before ASERVICE when Aservice was created;} public void setbService (BService bService) {this.bService = bService } @ Service@Scope ("prototype") public class BService {/ / @ Autowired public AService aService; public void setaService (AService aService) {this.aService = aService;}} public class SpringApp {public static void main (String [] args) {/ / 1. Will all singletons of the ioc container be created when AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext (MyConfig.class) / A pair of example cases when you get AService aSerivce = applicationContext.getBean ("AService", AService.class); BService bSerivce = applicationContext.getBean ("BService", BService.class); aSerivce.setbService (bSerivce); bSerivce.setaService (aSerivce); / / Loop reference exception cannot find an object / * think about the problem? What if our project object has to be multiple cases? And the circular reference must explicitly specify which object to reference * / String [] beanDefinitionNames = applicationContext.getBeanDefinitionNames (); for (int I = 0; I)
< beanDefinitionNames.length; i++) { System.out.println(beanDefinitionNames[i]); } SpringBean循环依赖三级缓存概念 思考问题:单例对象在什么时候创建? 在IOC容器被创建的时候创建 多例的情况下,是在getbean()调用的情况下创建。多例对象每次用完就会去销毁掉。 SpringBean Aservice对象被创建流程步骤源码分析AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class); // Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);// Instantiate all remaining (non-lazy-init) singletons.beanFactory.preInstantiateSingletons(); public Object getBean(String name) throws BeansException { return this.doGetBean(name, (Class)null, (Object[])null, false);} public Object getSingleton(String beanName) { return this.getSingleton(beanName, true);} 获取缓存对象: protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); //根据BeanName去集合中查,查到就返回这个对象,【】【】【】一级缓存对象集合【】【】【】缓存完整对象【】【】完整对象表示对象已经创建完了,并且对象属性已经赋值了。 if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) { Map var4 = this.singletonObjects; synchronized(this.singletonObjects) { singletonObject = this.earlySingletonObjects.get(beanName); //查询二级缓存中是否有缓存对象 if (singletonObject == null && allowEarlyReference) { ObjectFactory singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName); //查询三级缓存,三级缓存中有的化,将三级缓存中的数据放入二级缓存中 if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return singletonObject;} 一级缓存没有找到,就去找二级缓存中找 singletonObject == null && this.isSingletonCurrentlyInCreation(beanName) //一级缓存没有,并且singletonsCurrentlyInCreation判断是否之前标记为该对象开始创建 if (isPrototypeCurrentlyInCreation(beanName)) { //我们对象是单例的,所有不进入 throw new BeanCurrentlyInCreationException(beanName);} public Object getSingleton(String beanName, ObjectFactory singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized (this.singletonObjects) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction " + "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); } if (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet(); } try { singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime ->/ / if yes, proceed with it since the exception indicates that state. SingletonObject = this.singletonObjects.get (beanName); if (singletonObject = = null) {throw ex;}} catch (BeanCreationException ex) {if (recordSuppressedExceptions) {for (Exception suppressedException: this.suppressedExceptions) {ex.addRelatedCause (suppressedException);}} throw ex } finally {if (recordSuppressedExceptions) {this.suppressedExceptions = null;} afterSingletonCreation (beanName);} if (newSingleton) {addSingleton (beanName, singletonObject);}} return singletonObject;}}
Protected void beforeSingletonCreation (String beanName) {if (! this.inCreationCheckExclusions.contains (beanName) & &! this.singletonsCurrentlyInCreation.add (beanName)) {throw new BeanCurrentlyInCreationException (beanName);}}
Identification to start creation for this object
Final call
Really create our Bean object:
Since you want to create an object, first reflect the no-parameter constructor, instantiate the object first, and then assign the value
Execute this method to output the statement printed by the constructor, indicating that the underlying
Before that, our object was a baby object because its properties had not yet been assigned. Are called baby objects.
So when will the value be assigned?
PopulateBean (beanName, mbd, instanceWrapper); / / assign values to object properties here
Before assigning a value to an object property:
Protected void addSingletonFactory (String beanName, ObjectFactory singletonFactory) {Assert.notNull (singletonFactory, "Singleton factory must not be null"); synchronized (this.singletonObjects) {if (! this.singletonObjects.containsKey (beanName)) {/ / [] [] if the first-level cache does not have the object, the object will be stored in the third-level cache this.singletonFactories.put (beanName, singletonFactory) / / [] [] is stored in the third-level cache, and the object is instantiated, but no value is assigned. Baby object [] [] this.earlySingletonObjects.remove (beanName); this.registeredSingletons.add (beanName);}
An object insists on relying on B object, which also needs to be created.
The An object has been stored in the third-level cache, so it is time to create the B object
At this time, object B also has to follow the An object process.
Look at the call chain.
Also put the B object into the three-level cache
To sum up:
When the AService is created, the advance exposure is stored in the tertiary cache, and the AService finds that it depends on BService. At this time, the Bservice is pre-exposed and stored in the tertiary cache.
At this point, BService depends on AService. In this case, BService is assigned to be a complete object, but Aservice is still a baby object and has not been completely created.
The BService object is registered in the primary cache, and the secondary cache of the previously cached BService object is cleared.
The AService object depends on BService,BService, so AService assigns the BService to AService directly after setting the property.
Start registering AService objects
Summary:
The process of creating Aservic objects in SpringBean steps: source code analysis:
DoGetBean creates our bean object
GetSingleton (beanName) gets the cache object
Note: full object concept: the object has been instantiated successfully and all properties have been assigned
SingletonObjects first-level cache full object
EarlySingletonObjects secondary cache cache baby object
SingletonFactories three-level cache stores baby objects
Understand the concept:
The full object indicates that the object has been instantiated and all properties have been assigned.
The baby object (advance object) object has been instantiated but the property is not assigned.
SingletonObject = = null&&this.singletonsCurrentlyInCreation.contains (beanName)
{
To be able to query secondary cache
}
SingletonsCurrentlyInCreation: marked as the object to start creation
GetSingleton (String beanName, ObjectFactory singletonFactory)
This.singletonsCurrentlyInCreation.add (beanName) indicates that the object has been created
CreateBean () → doCreateBean
AddSingletonFactory stores baby objects (that is, incomplete objects that are only instantiated but whose properties are not assigned) in the tertiary cache.
The An object has been stored in the three-tier cache, and you need to create a B object when you start assigning values to the object properties.
An object check found that it depends on B object. At this time, B object also needs to be created.
The above is the solution to the problem of SpringBean circular dependency, and the editor believes that there are some knowledge points that we may see or use in our daily work. I hope you can learn more from this article. For more details, please follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.