Spring的新手 - 当应用程序上下文实例化所有bean时

时间:2015-04-25 09:53:16

标签: java spring spring-mvc

您好我从mkyong.com

获取了此代码
ApplicationContext context = 
      new ClassPathXmlApplicationContext(new String[] {"Spring-Customer.xml"});

    CustomerService cust = (CustomerService)context.getBean("customerService");

在上面的代码中,ApplicationContext实例化文件customerService中配置的bean Spring-Customer.xml的时间/地点。

<bean id="customerService" class="com.mkyong.customer.services.CustomerService">
    <property name="customerDAO" ref="customerDAO" />
</bean>

只需在new CustomerService()发生的时间/地点。

2 个答案:

答案 0 :(得分:3)

回答问题的最简单方法是在bean的构造函数中添加一个断点,看看调试时会发生什么。

我在一个随机java应用程序中添加了一个名为CrawlerManager的radom类中的断点。

这是bean的定义:

<bean id="crawlerManager" class="ro.geopatani.crawlers.CrawlerManager"/>

这是我得到的:

debug frames

    主要方法中的
  1. ApplicationContext实例化如下:

    public static void main (String ... args){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");    }
    
  2. 因为spring中的默认bean范围是singleton,所以这是单例bean的实例开始的时间点。

  3. 使用bean CrawlerManager

    的名称调用以下方法
    public Object getBean(String name) throws BeansException {
                return doGetBean(name, null, null, false);
    }
    

    3。调用Class.newInstance()并触发CrawlerManager的构造函数。

    还有一点很重要,方法AbstractApplicationContext.refresh()是从spring.xml文件加载所有bean定义的地方。

    以下是这种情况: debug frames-load beans

    以下是刷新方法的确切代码,您可以在其中看到对obtainFreshBeanFactory()的调用:

        public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();
    
            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);
    
            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);
    
                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);
    
                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);
    
                // Initialize message source for this context.
                initMessageSource();
    
                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();
    
                // Initialize other special beans in specific context subclasses.
                onRefresh();
    
                // Check for listener beans and register them.
                registerListeners();
    
                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);
    
                // Last step: publish corresponding event.
                finishRefresh();
            }
    
            catch (BeansException ex) {
                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();
    
                // Reset 'active' flag.
                cancelRefresh(ex);
    
                // Propagate exception to caller.
                throw ex;
            }
        }
    }
    

答案 1 :(得分:0)

在Spring中,每个单例bean都被急切地初始化。因此,当您加载上下文时,例如,当您在此时调用..new ClassPathXmlApplicationContext(new String[] {"Spring-Customer.xml"});时,将创建您的客户服务bean。

如果您想避免这种情况,可以在spring config xml中使用lazy-init="true"之类的属性。