【问题标题】:Spring bean instantiation orderingSpring bean 实例化排序
【发布时间】:2012-11-30 12:17:40
【问题描述】:

我遇到了 Bean 实例化排序很重要的问题。当前,下面的 Bean3 正在运行基于数据库的缓存放置操作,而 Bean 1 使用代理 Bean2 对新创建的缓存进行查询。优先级是 Bean3 和 Bean 2 在 Bean1 实例化之前完全实例化,即当 Spring 容器启动时。这些 bean 位于单独的 JARS 中,并且 Bean2 对 Bean1 的引用未使用 Autowired。相反,服务定位器正在给它一个参考。我们使用 Spring 2.5.2 而不是使用 XML 来实例化 bean。任何帮助表示赞赏!

  • JAR1(春季项目)

    @Service ("bean3")   
     public class Bean3 implements ApplicationListener  { 
        public void onApplicationEvent() {  
          //load data from DB and populate cache                    
        }
         public void getCache(){
         //get data from cache
        }
    

    }

    @Service ("bean2")
    public class Bean2 { 
    @Autowired 
    private Bean3 bean3;
       private void methodA(){
         bean3.getCache();
       }
    }
    
  • JAR2(非 Spring 项目)

    public class Bean1{  
    Bean2 bean2 = SpringServiceLocator.getBean("bean2")
      public void methodB(){
        bean2.methodA();
       } 
    }
    

【问题讨论】:

  • 你在使用基于构造函数的自动装配吗?
  • 我们在 JAR1 中启用了自动发现模式以进行自动装配。
  • 让 Bean1 依赖于 Bean2 是否可行(或创建依赖链?)何时调用来自 Bean1 的方法?
  • 对 Bean 1 的 Bean 2 引用由 Spring 服务定位器实用程序(自制)提供,因为 Bean1 位于非 Spring 项目中。我已经编辑了我的问题以更好地组织我的问题
  • 我假设在您的 init 方法上使用 @PostConstruct 可以解决您的问题。

标签: java spring jakarta-ee applicationcontext


【解决方案1】:

如果我理解正确,您正在尝试在应用程序启动时执行一些逻辑(上下文初始化)。

如果是这种情况,我建议您使用 BeanPostProcessor,在应用程序启动时执行任何特殊操作。

public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {

        .. **perform special things**
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        ..**perform special things**
        return bean;
    }
}

别忘了告诉 Spring 你的后处理器

<context:component-scan base-package="some.package" />
<bean class="some.package.MyBeanPostProcessor"

更多信息请阅读这里http://static.springsource.org/spring/docs/3.0.0.M3/reference/html/ch04s07.html

我希望这会有所帮助。

【讨论】:

    【解决方案2】:

    也许您的自制 Spring Service 定位器需要如下所示的信号

            Lock l = new ReentrantLock();
            Condition springready = l.newCondition();
    
            l.lock();
            try {
              while (READY_FLAG)
                  springready.await();
    
                ...
    
            } finally {
              l.unlock();
            }
    

    另外

    您可以通过监听 Co​​ntextRefreshedEvent 来更改 READY_FLAG 并发出“springready”信号

    【讨论】:

    • 由于某些原因,我无法分享我们正在使用的代码,但就是这样
    猜你喜欢
    • 2017-04-23
    • 1970-01-01
    • 1970-01-01
    • 2016-07-11
    • 2016-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多