publicstaticvoidmain(String[] args){ try { // retreive two different contexts ApplicationContext firstContext = new FileSystemXmlApplicationContext("/home/bartosz/webapp/src/main/resources/META-INF/applicationContext.xml"); ApplicationContext secondContext = new FileSystemXmlApplicationContext("/home/bartosz/webapp/src/main/resources/META-INF/applicationContext.xml");
// compare the objects from different contexts ShoppingCart firstShoppingCart = (ShoppingCart) firstContext.getBean("shoppingCart"); ShoppingCart secondShoppingCart = (ShoppingCart) secondContext.getBean("shoppingCart"); System.out.println("1. Are they the same ? " + (firstShoppingCart == secondShoppingCart));
// compare the objects from the same context ShoppingCart firstShoppingCartBis = (ShoppingCart) firstContext.getBean("shoppingCart"); System.out.println("2. Are they the same ? "+ (firstShoppingCart == firstShoppingCartBis)); } catch (Exception e) { e.printStackTrace(); } } }
通过执行此代码,你应该得到:
1. Are they the same ? false 2. Are they the same ? true
// after http://localhost:8080/addProduct/ice%20tea ShoppingCart is ShoppingCart {products: [Product {ice tea}]} // after http://localhost:8080/addProduct/milk ShoppingCart is ShoppingCart {products: [Product {milk}]}
/** * Simple template superclass for {@link FactoryBean} implementations that * creates a singleton or a prototype object, depending on a flag. * * <p>If the "singleton" flag is {@code true} (the default), * this class will create the object that it creates exactly once * on initialization and subsequently return said singleton instance * on all calls to the {@link #getObject()} method. * * <p>Else, this class will create a new instance every time the * {@link #getObject()} method is invoked. Subclasses are responsible * for implementing the abstract {@link #createInstance()} template * method to actually create the object(s) to expose. * * @author Juergen Hoeller * @author Keith Donald * @since 1.0.2 * @see #setSingleton * @see #createInstance() */ publicabstractclassAbstractFactoryBean<T> implementsFactoryBean<T>, BeanClassLoaderAware, BeanFactoryAware, InitializingBean, DisposableBean{ /** * Expose the singleton instance or create a new prototype instance. * @see #createInstance() * @see #getEarlySingletonInterfaces() */ @Override publicfinal T getObject()throws Exception { if (isSingleton()) { return (this.initialized ? this.singletonInstance : getEarlySingletonInstance()); } else { return createInstance(); } } ... /** * Template method that subclasses must override to construct * the object returned by this factory. * <p>Invoked on initialization of this FactoryBean in case of * a singleton; else, on each {@link #getObject()} call. * @return the object returned by this factory * @throws Exception if an exception occurred during object creation * @see #getObject() */ protectedabstract T createInstance()throws Exception; ... }
/** * A BeanDefinition describes a bean instance, which has property values, * constructor argument values, and further information supplied by * concrete implementations. * * <p>This is just a minimal interface: The main intention is to allow a * {@link BeanFactoryPostProcessor} such as {@link PropertyPlaceholderConfigurer} * to introspect and modify property values and other bean metadata. * * @author Juergen Hoeller * @author Rob Harrop * @since 19.03.2004 * @see ConfigurableListableBeanFactory#getBeanDefinition * @see org.springframework.beans.factory.support.RootBeanDefinition * @see org.springframework.beans.factory.support.ChildBeanDefinition */ publicinterfaceBeanDefinitionextendsAttributeAccessor, BeanMetadataElement{ //限于篇幅,请自行查看源码,能发现很多有用的东西 }
/** * Instantiate and invoke all registered BeanFactoryPostProcessor beans, * respecting explicit order if given. * <p>Must be called before singleton instantiation. */ protectedvoidinvokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory){ PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
/** * Instantiate and invoke all registered BeanPostProcessor beans, * respecting explicit order if given. * <p>Must be called before any instantiation of application beans. */ protectedvoidregisterBeanPostProcessors(ConfigurableListableBeanFactory beanFactory){ PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }
/** * Finish the initialization of this context's bean factory, * initializing all remaining singleton beans. */ protectedvoidfinishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory){ // Initialize conversion service for this context. if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); }
// Register a default embedded value resolver if no bean post-processor // (such as a PropertyPlaceholderConfigurer bean) registered any before: // at this point, primarily for resolution in annotation attribute values. if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); }
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); }
// Stop using the temporary ClassLoader for type matching. beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes. beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons. beanFactory.preInstantiateSingletons(); }
@Override publicvoidrefresh()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(); }
// Destroy already created singletons to avoid dangling resources. destroyBeans();
// Reset 'active' flag. cancelRefresh(ex);
// Propagate exception to caller. throw ex; }
finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }