In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly introduces "what is the registration of Bean in Spring Bean". In the daily operation, I believe that many people have doubts about the registration of Bean in Spring Bean. The editor consulted all kinds of materials and sorted out simple and easy-to-use methods of operation. I hope it will be helpful to answer the doubt of "what is the registration of Bean in Spring Bean?" Next, please follow the editor to study!
Preface
This paper mainly focuses on BeanDefinitionReaderUtils#registerBeanDefinition to analyze the Bean registration process.
Public static void registerBeanDefinition (BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {/ / Register bean definition under primary name. String beanName = definitionHolder.getBeanName (); registry.registerBeanDefinition (beanName, definitionHolder.getBeanDefinition ()); / / Register aliases for bean name, if any. String [] aliases = definitionHolder.getAliases (); if (aliases! = null) {for (String alias: aliases) {registry.registerAlias (beanName, alias);}
BeanDefinitionRegistry is used in both registering bd and establishing the relationship between alias-beanName, so we use it as a breakthrough.
The inheritance system of BeanFactory
Describe the interfaces or classes commonly used in the figure:
The ListableBeanFactory collection type BeanFactory provides the ability to find all Bean instances
GetBeanNamesForType (Class) looking up the list of Bean names based on type does not force initialization of Bean, as can be seen in the source code
GetBeansOfType (Class) looks up the list of Bean instances according to the type, which forces the initialization of Bean, as can be seen in the source code.
GetBeanNamesForAnnotation (Class) gets the list of Bean names based on the annotation type
GetBeansWithAnnotation (Class) gets the list of Bean instances based on the annotation type
FindAnnotationOnBean (String,Class) gets the Bean instance based on the specified name + dimension type
Hierarchical (["ha" container "r"k" kl]) BeanFactory hierarchical BeanFactory, with the concept of parent-son container, you can set its parent container in ConfigurableListableBeanFactory.
GetParentBeanFactory () gets the parent container
Boolean containsLocalBean (String name) looks for the existence of a Bean instance with that name in the current container
SingletonBeanRegistry single instance BeanFactory, related to single instance
ConfigurableBeanFactory configurable BeanFactory, which is generally not used in applications, is intended for other BeanFactory extensions. Indeed, many configuration methods are defined
BeanFactory of ConfigurableListableBeanFactory configurable collection type
AutowireCapableBeanFactory provides BeanFactory with automatic assembly capability
Through the inheritance system, we can see that the implementation class of BeanDefinitionRegistry is DefaultListableBeanFactory, which implements many interfaces at the same time, so it can be said to be the aggregator of BeanFactory, so we go to DefaultListableBeanFactory to read the source code of bd registration and alias registration.
Registration of Bean
Let's first analyze several important member attributes of DefaultListableBeanFactory.
/ / this is essentially the carrier of Bean in the IoC container, yes, it is important, but it is an unordered private final Map beanDefinitionMap = new ConcurrentHashMap (256); / / it represents a collection of bd names, which follows the order of bd registration private volatile List beanDefinitionNames = new ArrayList (256) / / this is a collection of created bd names. When the doGetBean method creates a Bean based on beanName, beanName is added to this collection private final Set alreadyCreated = Collections.newSetFromMap (new ConcurrentHashMap (256))
Both of the above two attributes are important. If they are used together, you can access bd sequentially (in fact, when traversing the beanDefinitionNames collection, use beanDefinitionMap to get bd).
Public void registerBeanDefinition (String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {/ / A pair of beanName and bd for non-empty verification Assert.hasText (beanName, "Bean name must not be empty"); Assert.notNull (beanDefinition, "BeanDefinition must not be null") / / if bd is an AbstractBeanDefinition type, validate the bd (generally speaking, the bd in our scenario is inherited from AbstractBeanDefinition) if (beanDefinition instanceof AbstractBeanDefinition) {try {/ / bd authentication ((AbstractBeanDefinition) beanDefinition) .validate () } catch (BeanDefinitionValidationException ex) {/ / omit exception code}} / / get bd BeanDefinition existingDefinition = this.beanDefinitionMap.get (beanName) from beanDefinitionMap according to beanName / / if the bd of the beanName name already exists if (existingDefinition! = null) {/ / if Bean is not allowed to be re-registered, an exception is thrown, where the default value is true if (! isAllowBeanDefinitionOverriding ()) {throw new BeanDefinitionOverrideException (beanName, beanDefinition, existingDefinition) } / / if the role value of the registered bd is less than the current role value of the bd to be registered else if (existingDefinition.getRole () < beanDefinition.getRole ()) {/ / omit log output} / / if the registered bd with the same name is different from the bd registered this time, else if (! beanDefinition.equals (existingDefinition)) {/ / omit the log output} else { / / omit log output} / / put the beanName-bd key-value pair into the beanDefinitionMap collection this.beanDefinitionMap.put (beanName BeanDefinition) } else {/ / process goes here to explain that there is no bd / / with the same name in beanDefinitionMap. If the condition is established, it means that alreadyCreated is not empty, that is, bd has been created if (hasBeanCreationStarted ()) { / / if a bean is being created in between, synchronized (this.beanDefinitionMap) {/ / put the beanName-bd key-value pair into the beanDefinitionMap collection this.beanDefinitionMap.put (beanName) BeanDefinition) / / add beanName to the beanDefinitionNames collection List updatedDefinitions = new ArrayList (this.beanDefinitionNames.size () + 1); updatedDefinitions.addAll (this.beanDefinitionNames); updatedDefinitions.add (beanName) This.beanDefinitionNames = updatedDefinitions / / if beanName is a singleton Bean name registered manually, update manualSingletonNames if (this.manualSingletonNames.contains (beanName)) {Set updatedSingletons = new LinkedHashSet (this.manualSingletonNames) / / personal understanding of the reason why it is deleted from the collection: / / manualSingletonNames records the single instance beanName added during registerSingleton, but the injection here is not single instance Bean. Because manualSingletonNames contains this beanName, you need to eliminate updatedSingletons.remove (beanName); this.manualSingletonNames = updatedSingletons } else {/ / if no bean is created / / put the beanName-bd key-value pair into the beanDefinitionMap Collection this.beanDefinitionMap.put (beanName BeanDefinition) / / add beanName to the collection this.beanDefinitionNames.add (beanName); / / remove it from the manualSingletonNames here, which is understood as a floor mop operation. After all, without this beanName in the collection, you cannot remove this.manualSingletonNames.remove (beanName). } / / this collection represents the beanName collection cached when the configuration is frozen. The purpose of this collection this.frozenBeanDefinitionNames = null is not understood yet. } / / if a bd with the same name or a singleton object with the same name already exists, reset all cached bd data with the same name, so after the bd registration is successful, the if of the Bean (existingDefinition! = null | | containsSingleton (beanName)) {resetBeanDefinition (beanName);}} will be generated later.
In fact, after analysis, it is relatively easy to understand the process of Bean registration, so let's try to summarize it:
If bd has not been registered, the bd information is stored in collections such as BeanDefinitionMap
If bd has been registered and override registration is allowed, store bd information in collections such as BeanDefinitionMap, and clear the cached bd information of the same name.
Let's take a look at the code logic that clears bd information.
Protected void resetBeanDefinition (String beanName) {/ / if this bd belongs to the merged BeanDefinition, clearMergedBeanDefinition (beanName) is removed from the MergeBeanDefinition collection; / / if a singleton object with the same name already exists, it is destroyed without expanding destroySingleton (beanName) for details. / / here the for loop logic is related to MergeBeanDefinition. If there is a MergedBeanDefinitionPostProcessor, reset the bd for (BeanPostProcessor processor: getBeanPostProcessors ()) {if (processor instanceof MergedBeanDefinitionPostProcessor) {((MergedBeanDefinitionPostProcessor) processor) .resetBeanDefinition (beanName) }} / / BeanDefinition runs hierarchical if the bd has more than one parent bd Then the parent bd for (String bdName: this.beanDefinitionNames) {if (! beanName.equals (bdName)) {BeanDefinition bd = this.beanDefinitionMap.get (bdName) is recursively reset here. Registration of if (beanName.equals (bd.getParentName () {resetBeanDefinition (bdName);}} alias aliases
Look at the registration of Bean, and then look at the alias registration discovery process is relatively clear, basically at a glance.
/ / Note that the name here should not be represented as beanName, although we trace back to public void registerAlias (String name, String alias) {/ / a pair of name and alias for assertion verification Assert.hasText (name, "'name' must not be empty") and Assert.hasText (alias, "' alias' must not be empty") from the establishment of the String name relationship. Synchronized (this.aliasMap) {/ / if the alias is the same as beanName, there is no need for the alias to exist, so choose to remove the alias if (alias.equals (name)) {this.aliasMap.remove (alias) directly from this.aliasMap / / omit log output} else {/ / get name String registeredName = this.aliasMap.get (alias) from aliasMap according to alias If (registeredName! = null) {/ / if the existing registeredName is the same as the name to be registered, then there is no need to register if (registeredName.equals (name)) {return } / / the process has come to this point, indicating the same alias Corresponding to two name, if alias overrides are not allowed, throw an exception if (! allowAliasOverriding ()) {/ / omit the exception and log output} / / check the alias loop here Avoid situations where the alias of An is Bmai B and the alias of B is A checkForAliasCircle (name, alias) / / put alias--name into aliasMap this.aliasMap.put (alias, name); / / omit log output}
The mapping relationship between alias and beanName provides another way to find Bean according to the name. That is to say, in addition to beanName, you can also find Bean according to alias.
The source code of this part is as follows
/ / name can be beanName or aliaspublic String canonicalName (String name) {/ / Local variable assignment String canonicalName = name; / / Handle aliasing... String resolvedName; do {/ / if beanName resolvedName = this.aliasMap.get (canonicalName); if (resolvedName! = null) {canonicalName = resolvedName can be parsed from aliasMap according to alias }} while (resolvedName! = null); / / whether the input parameter name is beanName or alias, the beanName should be returned here. Return canonicalName;} at this point, the study on "what is the registration of Bean in Spring Bean" is over. I hope you can solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
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.