Spring Bean的初始化
程序员文章站
2022-05-21 22:13:51
...
基于注解驱动
AnnotationConfigApplicationContext 为Spring Context、上下文、容器。
public static void main( String[] args )
{
AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext(App.class);
System.out.println(ac.getBean("example"));
}
Spring Bean工厂在代码的实现类为DefaultListableBeanFactory。该类实现了BeanFactory接口。
AnnotationConfigApplicationContext
构造方法
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
//注册Bean 类似于ac.register(App.class);
register(annotatedClasses);
//启动容器
refresh();
}
refresh()
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
/*
* 扫描类并将符合Spring规则的类解析成一个BeanDefinition对象
*
*/
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();
/*
* 调用该方法实例化对象
*
*/
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 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();
}
}
}
DefaultListableBeanFactory
该类中存储了一个beanDefinitionMap,用来存储解析的beanDefinition对象。该Map由CurrentHashMap实现。属于线程安全。
@SuppressWarnings("serial")
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
@Nullable
private static Class<?> javaxInjectProviderClass;
static {
try {
javaxInjectProviderClass =
ClassUtils.forName("javax.inject.Provider", DefaultListableBeanFactory.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - Provider interface simply not supported then.
javaxInjectProviderClass = null;
}
}
/** Map from serialized id to factory instance */
private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =
new ConcurrentHashMap<>(8);
/** Optional id for this factory, for serialization purposes */
@Nullable
private String serializationId;
...
Spring Bean的产生过程
对象与Spring Bean的关系:Spring Bean是一个对象,但对象不一定是Spring Bean
BeanDefinition :Bean的描述对象,描述Spring Bean的一个类。
首先JVM加载类并进行扫描,将符合Spring Bean规则的类解析成GenericBeanDefinition对象。并将对象放入beanDefinitionMap中。
模拟操作【将Class解析成一个BeanDefinition对象 】:
for{
//读取类的信息解析成BeanDefinition对象
//BeanDefinition对象:描述Bean的对象
GenericBeanDefinition beanDefinition=new GenericBeanDefinition();
beanDefinition.setBeanClassName(Example.class.getName());
beanDefinition.setBeanClass(Example.class);
beanDefinition.setScope("singleton");
beanDefinition.setLazyInit(false);
...
//解析完成后,将该对象放入map中进行存储
//map中存储的BeanDefinition对象,即Bean的描述对象
beanDefinitionMap.put("example",beanDefinition);
}
干预Spring加载Bean的过程
@Component
public class MyProcessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("example");
beanDefinition.setBeanClassName(Example2.class.getName());
}
}
Spring将Spring Bean解析成一个BeanDefinition描述对象,并存储到Map中,在没有实例化之前,会查看是否有BeanFactoryPostProcessor ,如果有就会执行,用来干预Bean的加载。