In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly explains "the use of loading Bean in Spring". The content of the explanation is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "the use of loading Bean in Spring".
1. Loading of Bean / / the previous two articles have analyzed the read configuration file and registered BeanDefinitionBeanFactory bf = new XmlBeanFactory (new ClassPathResource ("beanFactory.xml")); / / this analysis loads BeanMyTestBean bean = bf.getBean ("myTestBean", MyTestBean.class); public T getBean (String name, Class requiredType) throws BeansException {return doGetBean (name, requiredType, null, false) } protected T doGetBean (final String name, final Class requiredType, final Object [] args, boolean typeCheckOnly) {/ / convert the corresponding beanName, first remove the modifier & of FactoryBean, and take the final beanName (if any) represented by the specified alias final String beanName = transformedBeanName (name); Object bean; / / 1. Check whether there is a corresponding instance Object sharedInstance = getSingleton (beanName) in the cache or instance factory; if (sharedInstance! = null & & args = = null) {/ / 2. Return the corresponding instance, such as the FactoryBean example in the appendix. The above sharedInstance is the instance of CarFactoryBean, but / / the Car instance should be returned, so bean = getObjectForBeanInstance (sharedInstance, name, beanName, null) is handled in this method;} else {/ / attempts to solve the circular dependency only in singleton cases, otherwise an exception if (isPrototypeCurrentlyInCreation (beanName)) {throw new BeanCurrentlyInCreationException (beanName) is thrown directly. } / / if beanName does not exist in beanDefinitionMap, try to find BeanFactory parentBeanFactory = getParentBeanFactory () from parentBeanFactory; if (parentBeanFactory! = null & &! containsBeanDefinition (beanName)) {String nameToLookup = originalBeanName (name); if (args! = null) {return (T) parentBeanFactory.getBean (nameToLookup, args);} else {return parentBeanFactory.getBean (nameToLookup, requiredType) }} if (! typeCheckOnly) {markBeanAsCreated (beanName);} try {final RootBeanDefinition mbd = getMergedLocalBeanDefinition (beanName); checkMergedBeanDefinition (mbd, beanName, args); / / bean String [] dependsOn = mbd.getDependsOn () that needs to be recursively instantiated if there is a dependency If (dependsOn! = null) {for (String dependsOnBean: dependsOn) {getBean (dependsOnBean); registerDependentBean (dependsOnBean, beanName);}} / / 3. Get the singleton bean if (mbd.isSingleton ()) {sharedInstance = getSingleton (beanName, new ObjectFactory () {public Object getObject () throws BeansException {try {return createBean (beanName, mbd, args);} catch (BeansException ex) {destroySingleton (beanName) Throw ex;}); bean = getObjectForBeanInstance (sharedInstance, name, beanName, mbd);} else if (mbd.isPrototype ()) {Object prototypeInstance = null; try {beforePrototypeCreation (beanName); prototypeInstance = createBean (beanName, mbd, args) } finally {afterPrototypeCreation (beanName);} bean = getObjectForBeanInstance (prototypeInstance, name, beanName, mbd);} else {String scopeName = mbd.getScope (); final Scope scope = this.scopes.get (scopeName) Try {Object scopedInstance = scope.get (beanName, new ObjectFactory () {public Object getObject () throws BeansException {beforePrototypeCreation (beanName); try {return createBean (beanName, mbd, args) } finally {afterPrototypeCreation (beanName);}); bean = getObjectForBeanInstance (scopedInstance, name, beanName, mbd) } catch (IllegalStateException ex) {}} catch (BeansException ex) {cleanupAfterBeanCreationFailure (beanName); throw ex;}} if (requiredType! = null & & bean! = null & &! requiredType.isAssignableFrom (bean.getClass () {try {return getTypeConverter (). ConvertIfNecessary (bean, requiredType) } catch (TypeMismatchException ex) {} return (T) bean;} step 1:Object sharedInstance = getSingleton (beanName); public Object getSingleton (String beanName) {/ / Parameter true indicates that the setting allows early dependency on return getSingleton (beanName, true);} protected Object getSingleton (String beanName, boolean allowEarlyReference) {/ / first attempts to load from the cache, singletonObjects = new ConcurrentHashMap (64); Object singletonObject = this.singletonObjects.get (beanName) If (singletonObject = = null & & isSingletonCurrentlyInCreation (beanName)) {/ / if empty, lock global variables for processing synchronized (this.singletonObjects) {/ / singletonObject = this.earlySingletonObjects.get (beanName) if this bean is being loaded; if (singletonObject = = null & & allowEarlyReference) {ObjectFactory singletonFactory = this.singletonFactories.get (beanName) If (singletonFactory! = null) {/ / calls the preset getObject method singletonObject = singletonFactory.getObject (); this.earlySingletonObjects.put (beanName, singletonObject); this.singletonFactories.remove (beanName);}} return (singletonObject! = NULL_OBJECT? SingletonObject: null);} step 2:bean = getObjectForBeanInstance (sharedInstance, name, beanName, null)
Protected Object getObjectForBeanInstance (Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {/ / verify. If the specified name is factory dependent, starts with &, and is not of FactoryBean type, the verification does not pass if (BeanFactoryUtils.isFactoryDereference (name) & &! (beanInstance instanceof FactoryBean)) {throw new BeanIsNotAFactoryException (transformedBeanName (name), beanInstance.getClass ()) } / / A normal bean is returned directly, or if the user wants to take a bean of FactoryBean type (name starts with &), return if (! (beanInstance instanceof FactoryBean) | | BeanFactoryUtils.isFactoryDereference (name)) {return beanInstance;} Object object = null; if (mbd = = null) {object = getCachedObjectForFactoryBean (beanName);} if (object = = null) {/ / get FactoryBean factory = (FactoryBean) beanInstance from the cache If (mbd = = null & & containsBeanDefinition (beanName)) {mbd = getMergedLocalBeanDefinition (beanName);} boolean synthetic = (mbd! = null & & mbd.isSynthetic ()); object = getObjectFromFactoryBean (factory, beanName,! synthetic);} return object Step 3: get the singleton beanpublic Object getSingleton (String beanName, ObjectFactory singletonFactory) {/ / global variable lock synchronized (this.singletonObjects) {/ / check whether it has been created in the cache, and initialize Object singletonObject = this.singletonObjects.get (beanName) if it is empty. If (singletonObject = = null) {/ / record the load status. The key step is to put the bean you are creating into singletonsCurrentlyInCreation to detect circular dependency beforeSingletonCreation (beanName); try {/ / instantiates bean through the incoming singletonFactory, callback singletonObject = singletonFactory.getObject () } catch (BeanCreationException ex) {} finally {/ / contrary to the loading state of the record, remove the loaded record afterSingletonCreation (beanName) after the creation is completed;} / / after the creation is completed, put it into the cache and delete the various auxiliary states addSingleton (beanName, singletonObject) during the loading of the bean } return (singletonObject! = NULL_OBJECT? SingletonObject: null);}} protected void beforeSingletonCreation (String beanName) {if (! this.inCreationCheckExclusions.containsKey (beanName) & & this.singletonsCurrentlyInCreation.put (beanName, Boolean.TRUE)! = null) {throw new BeanCurrentlyInCreationException (beanName);}} protected void addSingleton (String beanName, Object singletonObject) {synchronized (this.singletonObjects) {this.singletonObjects.put (beanName, (singletonObject! = null?) SingletonObject: NULL_OBJECT); this.singletonFactories.remove (beanName); this.earlySingletonObjects.remove (beanName); this.registeredSingletons.add (beanName);} / / the above callback to create bean singletonObject = singletonFactory.getObject (); public Object getObject () throws BeansException {return createBean (beanName, mbd, args);} protected Object createBean (final String beanName, final RootBeanDefinition mbd, final Object [] args) {try {/ / 1. If a methodOverides attribute is detected when instantiating lookup-method and replace-method,bean, a proxy will be dynamically generated for the current bean and the corresponding interceptor will be used to enhance the bean. The relevant logic will be analyzed when the bean is instantiated. Here, just check mbd.prepareMethodOverrides (). } try {/ / give BeanPostProcessors a chance to return the agent to replace the real instance Object bean = resolveBeforeInstantiation (beanName, mbd); / / short circuit. If the processed bean is not empty, then the bean,AOP function of returning the agent directly is based on the judgment here. The later analysis of if (bean! = null) {return bean }} / / create regular bean Object beanInstance = doCreateBean (beanName, mbd, args); return beanInstance;} protected Object doCreateBean (final String beanName, final RootBeanDefinition mbd, final Object [] args) {BeanWrapper instanceWrapper = null; / / if it is a singleton to clear cache if (mbd.isSingleton ()) {instanceWrapper = this.factoryBeanInstanceCache.remove (beanName) } / / instantiate Bean and convert BeanDefinition to BeanWrapper. The process is complex / / a. If there is a factory method, initialize / / b using the factory method. If there are multiple constructors, initialize / / c according to the parameter lock constructor, if there is neither factory method nor parameter constructor. Initialize if (instanceWrapper = = null) {instanceWrapper = createBeanInstance (beanName, mbd, args) with the default constructor } / /... Omitting the subsequent code, first analyze createBeanInstance} protected BeanWrapper createBeanInstance (String beanName, RootBeanDefinition mbd, Object [] args) {/ / parse beanClass Class beanClass = resolveBeanClass (mbd, beanName); / / 1. If there is a factory method, initialize and return it using the factory method. See Appendix 2 if (mbd.getFactoryMethodName ()! = null) {return instantiateUsingFactoryMethod (beanName, mbd, args);} / / if there is no factory method, initialize boolean resolved = false; boolean autowireNecessary = false using the constructor If (args = = null) {synchronized (mbd.constructorArgumentLock) {if (mbd.resolvedConstructorOrFactoryMethod! = null) {resolved = true; autowireNecessary = mbd.constructorArgumentsResolved } / / if the cache has been parsed, call the constructor directly to initialize if (resolved) {if (autowireNecessary) {/ / initialize return autowireConstructor (beanName, mbd, null, null) with the parameterized constructor;} else {/ / use the default constructor return instantiateBean (beanName, mbd) }} / / the constructor Constructor [] ctors = determineConstructorsFromBeanPostProcessors (beanClass, beanName) needs to be parsed according to the parameters; if (ctors! = null | | mbd.getResolvedAutowireMode () = = RootBeanDefinition.AUTOWIRE_CONSTRUCTOR | | mbd.hasConstructorArgumentValues () | |! ObjectUtils.isEmpty (args)) {/ / the parameter constructor return autowireConstructor (beanName, mbd, ctors, args) } / / default constructor return instantiateBean (beanName, mbd);} 1. Initialization using the factory method goes through a series of processing, and initialization using the factory method will eventually be called here
BeanInstance = beanFactory.getInstantiationStrategy (). Instantiate (mbd, beanName, beanFactory, factoryBean, factoryMethodToUse, argsToUse); public Object instantiate (RootBeanDefinition beanDefinition, String beanName, BeanFactory owner, Object factoryBean, final Method factoryMethod, Object [] args) {ReflectionUtils.makeAccessible (factoryMethod) / / use reflection to call factory methods return factoryMethod.invoke (factoryBean, args);} public Object invoke (Object obj, Object...) Args) {MethodAccessor ma = methodAccessor; / / debug found that the factory method return ma.invoke (obj, args);} public static FactoryMethodBean getInstance () {return new FactoryMethodBean ();} 2. Initialize with the parameter constructor, no parameter constructor is easier, because there is no need to locate the constructor, the creation of an object is similar to initialization using the parameter constructor, and will eventually be called here.
BeanInstance = this.beanFactory.getInstantiationStrategy () .instantiate (mbd, beanName, this.beanFactory, constructorToUse, argsToUse) Public Object instantiate (RootBeanDefinition beanDefinition, String beanName, BeanFactory owner, final Constructor ctor, Object [] args) {/ / if there is a method that needs to be overridden or dynamically replaced, use the CGLIB dynamic proxy You can dynamically weave methods such as if (beanDefinition.getMethodOverrides (). IsEmpty ()) in the class while creating the proxy {/ / if reflection is not called directly to construct the instance object return BeanUtils.instantiateClass (ctor, args) } else {return instantiateWithMethodInjection (beanDefinition, beanName, owner, ctor, args);}} public static T instantiateClass (Constructor ctor, Object...) Args) throws BeanInstantiationException {try {ReflectionUtils.makeAccessible (ctor); / / call reflection to construct the object return ctor.newInstance (args);}} Appendix 1, FactoryBean uses the public interface FactoryBean {/ / core method to return the bean instance T getObject () throws Exception; Class getObjectType () created by FactoryBean; boolean isSingleton ();} public class Car {private int maxSpeed; private String brand; private double price Public int getMaxSpeed () {return maxSpeed;} public void setMaxSpeed (int maxSpeed) {this.maxSpeed = maxSpeed;} public String getBrand () {return brand;} public void setBrand (String brand) {this.brand = brand;} public double getPrice () {return price;} public void setPrice (double price) {this.price = price }} public class CarFactoryBean implements FactoryBean {private String carInfo; public Car getObject () throws Exception {Car car = new Car (); String [] infos = carInfo.split (","); car.setBrand (infos [0]); car.setMaxSpeed (Integer.valueOf (infos [1])); car.setPrice (Double.valueOf (infos [2])); return car } public Class getObjectType () {return Car.class;} public boolean isSingleton () {return true;} public String getCarInfo () {return carInfo;} public void setCarInfo (String carInfo) {this.carInfo = carInfo }} when getBean is called, Spring discovers that CarFactoryBean implements the FactoryBean interface through the reflection mechanism, and the Spring container calls the interface method getObject () to return the Bean instance. If you want to get an instance of CarFactoryBean, you need to use the getBean (beanName) method to prefix the beanName with &, for example, getBean ("& car") .2, factory method factory-methodpublic class FactoryMethodBean {private String str = "lwh sayHello"; public String getStr () {return str;} public void setStr (String str) {this.str = str;} public static FactoryMethodBean getInstance () {return new FactoryMethodBean () }} Thank you for your reading, the above is the content of "loading Bean in Spring". After the study of this article, I believe you have a deeper understanding of the use of loading Bean in Spring, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
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.