whm9276 2017-09-14 02:42 采纳率: 0%
浏览 875

Spring factoryBean加载 框架内部嵌套加载问题

各位大神,最近在研究spring框架bean加载过程,遇到一个棘手问题,我相信研究spring原理的大神肯定对这个问题有兴趣

我的项目框架是spring+rpc,配置文件方式注入bean,非注解

一部分bean是普通的serivce bean配置,spring内部走正常bean的加载过程,没有问题;

还有一部分是自定义标签,通过一个工厂类生成service的代理对象bean,作为消费者/生产者,这个工厂类实现了FactoryBean接口,spring内部走FactoryBean的加载过程
public class RemoteServiceFactory implements FactoryBean, BeanFactoryAware, InitializingBean {
private static final Logger log = LoggerFactory.getLogger(RemoteServiceFactory.class);
 public RemoteServiceFactory(Object bean, String path, int port) {
  this.object = bean; // 自定义标签中配置的service bean的引用(ref属性,引用配置文件bean id)
  this.path = path; // 生产者服务路径(和此问题无关)
  this.port = port; // 生产者服务端口(和此问题无关)
 }
 
 public boolean isSingleton() {
  return true;
 }
 public void afterPropertiesSet() throws Exception {
   // 根据this.object创建相应的生产者/消费者代理对象,用于rpc
 }
}

问题分析,debug spring bean解析后的加载过程
1.spring对配置文件解析后,遍历所有的bean,进行一一实例化
  AbstractApplicationContext:finishBeanFactoryInitialization()
    内部调用beanFactory.preInstantiateSingletons();
      DefaultListableBeanFactory:preInstantiateSingletons()
        内部遍历beanNames,进行一一实例化

2.假如第一个bean是普通的service bean,在初始化时,会解析内部的依赖,然后遍历依赖参数,解析依赖
  DefaultListableBeanFactory:doResolveDependency()
    内部调用findAutowireCandidates() 
      内部调用BeanFactoryUtils.beanNamesForTypeIncludingAncestors()
        内部调用lbf.getBeanNamesForType()
          -> DefaultListableBeanFactory:doGetBeanNamesForType()
  关键就在这里,doGetBeanNamesForType方法内部会遍历所有bean,去判断是否匹配上面的依赖参数的类型,
  当遍历到实现FactoryBean的bean时,会实例化这个bean(因为FactoryBean只是代理,不是真正bean),然后又会解析factoryBean中真实bean中的依赖参数,
  然后就又会走到这里,导致一直嵌套下去的加载过程
  如果程序加载没有问题,则一切正常;一旦某个类加载失败(比如某个类注入的属性在properties中不存在),就会出现大量的异常信息抛出,
  原因就是上面的嵌套加载,某个类加载抛出异常会一直抛出到嵌套的最顶层,每一层的异常信息都会积攒下来,最后爆发似的抛出
  (每层的异常信息都是 当前这层bean的加载失败)

各位大神:
  我一直感觉spring这样嵌套加载在设计上是不应该的,不理解为什么会这样,单纯匹配类型的话,不能通过其他方式获取FactoryBean中真实bean的类型吗?
    为什么非要实例化它呢?有什么方法可以解决这个问题?

  • 写回答

1条回答 默认 最新

  • whm9276 2017-09-25 05:57
    关注

    顶起来,哪位大神帮看下

    评论

报告相同问题?

悬赏问题

  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突