千家信息网

Spring中加载Bean的使用方法

发表于:2025-01-26 作者:千家信息网编辑
千家信息网最后更新 2025年01月26日,这篇文章主要讲解了"Spring中加载Bean的使用方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Spring中加载Bean的使用方法"吧!1、B
千家信息网最后更新 2025年01月26日Spring中加载Bean的使用方法

这篇文章主要讲解了"Spring中加载Bean的使用方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Spring中加载Bean的使用方法"吧!

1、Bean的加载

// 前面两篇已经分析了读取配置文件,并注册BeanDefinitionBeanFactory bf = new XmlBeanFactory(new ClassPathResource("beanFactory.xml"));
// 这篇分析加载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){   //转换对应的beanName,先是去除FactoryBean的修饰符&,取指定alias所表示的最终beanName(如果存在的话)   final String beanName = transformedBeanName(name);   Object bean;   //1.检查缓存中或者实例工厂中是否有对应的实例   Object sharedInstance = getSingleton(beanName);   if (sharedInstance != null && args == null) {      //2.返回对应的实例,如附录中的FactoryBean例子,上面的sharedInstance是CarFactoryBean的实例,但是      //实际应当返回Car实例,因此在该方法中会做处理      bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);   }   else {      //只有在单例情况下才尝试解决循环依赖,否则直接抛异常      if (isPrototypeCurrentlyInCreation(beanName)) {         throw new BeanCurrentlyInCreationException(beanName);      }            //如果beanDefinitionMap不存在beanName则尝试从parentBeanFactory中寻找      BeanFactory parentBeanFactory = getParentBeanFactory();      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();         if (dependsOn != null) {            for (String dependsOnBean : dependsOn) {               getBean(dependsOnBean);               registerDependentBean(dependsOnBean, beanName);            }         }                  //3.获取单例的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;}
步骤1:Object sharedInstance = getSingleton(beanName);
public Object getSingleton(String beanName) {   //参数true表示设置允许早期依赖   return getSingleton(beanName, true);}protected Object getSingleton(String beanName, boolean allowEarlyReference) {   //首先尝试从缓存中加载,singletonObjects = new ConcurrentHashMap(64);   Object singletonObject = this.singletonObjects.get(beanName);   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {      //如果为空,则锁定全局变量进行处理      synchronized (this.singletonObjects) {         //如果此bean正在加载则不处理         singletonObject = this.earlySingletonObjects.get(beanName);         if (singletonObject == null && allowEarlyReference) {            ObjectFactory singletonFactory = this.singletonFactories.get(beanName);            if (singletonFactory != null) {               //调用预先设定的getObject方法               singletonObject = singletonFactory.getObject();               this.earlySingletonObjects.put(beanName, singletonObject);               this.singletonFactories.remove(beanName);            }         }      }   }   return (singletonObject != NULL_OBJECT ? singletonObject : null);}
步骤2:bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);

protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {   //验证,若指定的name是工厂相关,以&开头,又不是FactoryBean类型则验证不通过   if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)){      throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());   }   //是正常的bean直接返回,或者用户想取的就是FactoryBean类型的bean(name以&开头)则直接返回   if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)){      return beanInstance;   }   Object object = null;   if (mbd == null) {      object = getCachedObjectForFactoryBean(beanName);   }   if (object == null) {      //从缓存中获取      FactoryBean factory = (FactoryBean) beanInstance;            if (mbd == null && containsBeanDefinition(beanName)) {         mbd = getMergedLocalBeanDefinition(beanName);      }      boolean synthetic = (mbd != null && mbd.isSynthetic());      object = getObjectFromFactoryBean(factory, beanName, !synthetic);   }   return object;}
步骤3:获取单例的bean
public Object getSingleton(String beanName, ObjectFactory singletonFactory) {   //全局变量上锁   synchronized (this.singletonObjects) {      //检查缓存中是否已经创建,如果为空才可以初始化      Object singletonObject = this.singletonObjects.get(beanName);      if (singletonObject == null) {         //记录加载状态,关键的一步,将正在创建的bean放入singletonsCurrentlyInCreation,用于检测循环依赖         beforeSingletonCreation(beanName);                 try {            //通过传入的singletonFactory实例化bean,回调            singletonObject = singletonFactory.getObject();         }         catch (BeanCreationException ex) {}         finally {            //和记录加载状态相反,创建完成之后移除正在加载的记录            afterSingletonCreation(beanName);         }         //创建完成之后,将其放入缓存中,并删除加载bean过程中的各种辅助状态         addSingleton(beanName, singletonObject);      }      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);   }}//上述回调进行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.处理lookup-method和replace-method,bean实例化的时候若检测到有methodOverides属性,会动态地      //为当前bean生成代理并使用对应的拦截器为bean做增强处理,相关逻辑在bean实例化时会分析,此处仅是做下校验      mbd.prepareMethodOverrides();   }   try {      //给BeanPostProcessors一个机会来返回代理替代真正的实例      Object bean = resolveBeforeInstantiation(beanName, mbd);      //短路,若经过处理的bean不为空,则直接返回代理的bean,AOP功能就是基于这里的判断,后面分析      if (bean != null) {         return bean;      }   }    //进行常规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 (mbd.isSingleton()) {      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);   }   //实例化Bean,将BeanDefinition转换为BeanWrapper,该过程比较复杂   //a、存在工厂方法就使用工厂方法初始化   //b、若有多个构造函数,则根据参数锁定构造函数初始化   //c、若既不存在工厂方法,也不存在带参构造函数,则使用默认构造函数初始化   if (instanceWrapper == null) {      instanceWrapper = createBeanInstance(beanName, mbd, args);   }   //...省略后续代码,先分析createBeanInstance}
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {   //解析beanClass   Class beanClass = resolveBeanClass(mbd, beanName);      //1.若存在工厂方法,就使用工厂方法初始化并返回,工厂方法用例见附录2   if (mbd.getFactoryMethodName() != null)  {      return instantiateUsingFactoryMethod(beanName, mbd, args);   }      //若不存在工厂方法则使用构造函数初始化   boolean resolved = false;   boolean autowireNecessary = false;   if (args == null) {      synchronized (mbd.constructorArgumentLock) {         if (mbd.resolvedConstructorOrFactoryMethod != null) {            resolved = true;            autowireNecessary = mbd.constructorArgumentsResolved;         }      }   }   //如果已经解析缓存了,则直接调用构造函数初始化   if (resolved) {      if (autowireNecessary) {          //使用带参构造函数初始化          return autowireConstructor(beanName, mbd, null, null);      }      else {         //使用默认构造函数         return instantiateBean(beanName, mbd);      }   }   //需要根据参数解析构造函数   Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);   if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||                                                   mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {      //带参构造函数      return autowireConstructor(beanName, mbd, ctors, args);   }   //默认构造函数   return instantiateBean(beanName, mbd);}
1、使用工厂方法初始化经过一系列处理,使用工厂方法初始化最终会调用到此处

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);      //使用反射调用工厂方法      return factoryMethod.invoke(factoryBean, args);}public Object invoke(Object obj, Object... args){     MethodAccessor ma = methodAccessor;    //debug时发现此处会调用工厂方法    return ma.invoke(obj, args);}public static FactoryMethodBean getInstance(){    return new FactoryMethodBean();}
2、使用带参构造函数初始化,无参构造函数更简单,因为不需要定位构造函数,创建对象类似使用带参构造函数初始化,最终会调用到此处.

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) {   //如果有需要覆盖或者动态替换的方法则使用CGLIB动态代理,可以在创建代理的同时动态将方法织如类中   if (beanDefinition.getMethodOverrides().isEmpty()) {      //如果没有直接调用反射来构造实例对象       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);      //调用反射进行构造对象      return ctor.newInstance(args);   }}
附录1、FactoryBean的使用
public interface FactoryBean {   //核心方法,让实现类实现的,返回由FactoryBean创建的bean实例   T getObject() throws Exception;   Class getObjectType();   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;    }}
    
当调用getBean时,Spring通过反射机制发现CarFactoryBean实现了FactoryBean接口,这时Spring容器就调用接口方法getObject()返回Bean实例.如果希望获取CarFactoryBean的实例,需要使用getBean(beanName)方法时在beanName前显示加上&前缀,例如getBean("&car").
2、工厂方法factory-method
public 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();    }}

感谢各位的阅读,以上就是"Spring中加载Bean的使用方法"的内容了,经过本文的学习后,相信大家对Spring中加载Bean的使用方法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

0