千家信息网

Spring中加载Bean的使用方法

发表于:2024-10-14 作者:千家信息网编辑
千家信息网最后更新 2024年10月14日,这篇文章主要讲解了"Spring中加载Bean的使用方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Spring中加载Bean的使用方法"吧!1、B
千家信息网最后更新 2024年10月14日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的使用方法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

方法 函数 实例 工厂 缓存 处理 中加 代理 分析 使用方法 动态 反射 参数 对象 就是 正在 步骤 状态 附录 学习 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 db2怎么查询本地数据库 金蝶数据库升级失败 ecshop链接数据库 网络安全执法视频 再发生危害网络安全的视频 山东省大学生网络技术比赛内容 2021网络安全宣传周宣传主题 网络安全事件应急响应最高级别 创建icloud服务器错误 网络安全规定有下列行为之一 战地五不能收藏私人服务器 淮南龙亿互联网科技马金诚 网络技术员 招聘 《网络安全法》第59条规定 魔兽世界玛诺加尔服务器为什么关了 菜刀 更新数据库发生错误 数据库语句可以小写不 pchmi用什么软件开发 我的世界如何卡蹦基岩版服务器 lol战争学院服务器 软件开发加话 网络安全事件应急响应最高级别 裸金属服务器的配置步骤 青浦区新能源软件开发厂家价格 信息和网络安全承诺书 计算机网络技术基础考点 贵阳银行招软件开发人工资高 平度软件开发哪家便宜 徐州互联网智慧工厂软件开发 软件开发接口合作公司
0