/** * Prepare this context for refreshing, setting its startup date and * active flag as well as performing any initialization of property sources. */ protectedvoidprepareRefresh(){ // Switch to active. this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true);
if (logger.isDebugEnabled()) { if (logger.isTraceEnabled()) { logger.trace("Refreshing " + this); } else { logger.debug("Refreshing " + getDisplayName()); } }
// Initialize any placeholder property sources in the context environment. initPropertySources();
// Validate that all properties marked as required are resolvable: // see ConfigurablePropertyResolver#setRequiredProperties getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners... if (this.earlyApplicationListeners == null) { this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); } else { // Reset local application listeners to pre-refresh state. this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); }
// Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available... this.earlyApplicationEvents = new LinkedHashSet<>(); }
obtainFreshBeanFactory()
This implementation performs an actual refresh of this context’s underlying bean factory, shutting down the previous bean factory (if any) and initializing a fresh bean factory for the next phase of the context’s lifecycle.
/** * Configure the factory's standard context characteristics, * such as the context's ClassLoader and post-processors. * @param beanFactory the BeanFactory to configure */ protectedvoidprepareBeanFactory(ConfigurableListableBeanFactory beanFactory){ // Tell the internal bean factory to use the context's class loader etc. beanFactory.setBeanClassLoader(getClassLoader()); beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks. beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory. // MessageSource registered (and found for autowiring) as a bean. beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found. if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); }
// Register default environment beans. if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }
postProcessBeanFactory(beanFactory)
Allows post-processing of the bean factory in context subclasses.
Modify the application context’s internal bean factory after its standard initialization. All bean definitions will have bean loaded, but no beans have been instantiated yet. This alllows for registering special BeanPostProcessors etc in certain Applicationcontext implementations.
invokeBeanFactoryPostProcessors(beanFactory);
invoke factory processors registered as beans in the creation.
Instantiate and invoke all registered BeanFactoryPostProcessor beans, respecting explicit order if given. Must be called before singleton instantiation.
/** * Initialize the given bean instance, applying factory callbacks * as well as init methods and bean post processors. * <p>Called from {@link #createBean} for traditionally defined beans, * and from {@link #initializeBean} for existing bean instances. * @param beanName the bean name in the factory (for debugging purposes) * @param bean the new bean instance we may need to initialize * @param mbd the bean definition that the bean was created with * (can also be {@code null}, if given an existing bean instance) * @return the initialized bean instance (potentially wrapped) * @see BeanNameAware * @see BeanClassLoaderAware * @see BeanFactoryAware * @see #applyBeanPostProcessorsBeforeInitialization * @see #invokeInitMethods * @see #applyBeanPostProcessorsAfterInitialization */ protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd){ if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); returnnull; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); }
A BeanDefinition describes a bean instance, which has property values, Constructor arguments values, and further information supplied by concrete implementations. This is just a minimal interface: The main intention is to allow a BeanFactoryPostProcessor to introspect and modify property values and other bean metadata.
/** * Generate a bean name for the given bean definition, unique within the * given bean factory. * @param definition the bean definition to generate a bean name for * @param registry the bean factory that the definition is going to be * registered with (to check for existing bean names) * @param isInnerBean whether the given bean definition will be registered * as inner bean or as top-level bean (allowing for special name generation * for inner beans versus top-level beans) * @return the generated bean name * @throws BeanDefinitionStoreException if no unique name can be generated * for the given bean definition */ publicstatic String generateBeanName( BeanDefinition definition, BeanDefinitionRegistry registry, boolean isInnerBean) throws BeanDefinitionStoreException {
/** * Turn the given bean name into a unique bean name for the given bean factory, * appending a unique counter as suffix if necessary. * @param beanName the original bean name * @param registry the bean factory that the definition is going to be * registered with (to check for existing bean names) * @return the unique bean name to use * @since 5.1 */ publicstatic String uniqueBeanName(String beanName, BeanDefinitionRegistry registry){ String id = beanName; int counter = -1;
// Increase counter until the id is unique. while (counter == -1 || registry.containsBeanDefinition(id)) { counter++; id = beanName + GENERATED_BEAN_NAME_SEPARATOR + counter; } return id; }
@Override public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry){ if (definition instanceof AnnotatedBeanDefinition) { String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition); if (StringUtils.hasText(beanName)) { // Explicit bean name found. return beanName; } } // Fallback: generate a unique default bean name. return buildDefaultBeanName(definition, registry); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/** * Derive a default bean name from the given bean definition. * <p>The default implementation simply builds a decapitalized version * of the short class name: e.g. "mypackage.MyJdbcDao" -> "myJdbcDao". * <p>Note that inner classes will thus have names of the form * "outerClassName.InnerClassName", which because of the period in the * name may be an issue if you are autowiring by name. * @param definition the bean definition to build a bean name for * @return the default bean name (never {@code null}) */ protected String buildDefaultBeanName(BeanDefinition definition){ String beanClassName = definition.getBeanClassName(); Assert.state(beanClassName != null, "No bean class name set"); String shortClassName = ClassUtils.getShortName(beanClassName); return Introspector.decapitalize(shortClassName); }
// System.out.println(applicationContext.getBean(Config.class)); } @Component staticclassConfig{ @Bean public User user(){ User user = new User(); user.setId(1L); user.setName("Ann: zhangsan"); return user; } } }