spring源码解析
简单的主类:
@Configuration
@ComponentScan("cn.zhutan.test.import_anno.beanpostprocessor")
public class DemoTest {
@SuppressWarnings("resource")
public static void main(String[] args) {
ApplicationContext ac = new AnnotationConfigApplicationContext(DemoTest.class);
User user = ac.getBean(User.class);
System.out.println(user);
}
}
ApplicationContext ac = new AnnotationConfigApplicationContext(DemoTest.class);
这行代码是核心,到底干了什么?
先明白spring的目的就是创建bean对象,一般分为以下两步:
①创建beanDefinition(beanDefinition就是用来描述bean信息的,比如是否单例,懒加载等)
②通过beanDefinition创建bean(bean就是具体对象)
只不过在创建beanDefinition前后和创建bean前后会调用一些前后处理器等等操作
点开new AnnotationConfigApplicationContext(DemoTest.class),源码如下:
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//this方法会调用父类的构造方法,初始化一些变量,可以暂时先不看
this();
//register方法就是创建beanDefinition并注入容器,后续通过beanDefinition创建bean
register(annotatedClasses);
//refresh方法是重点,解释一下核心的功能
refresh();
}
点开refresh方法,写有注释的为重点方法:(不懂后面有解释)
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
//注册几个beanPostProcessor
postProcessBeanFactory(beanFactory);
//获取spring内部和我们添加的BeanFactoryPostProcessor&BeanDefinitionRegistryPostProcessor子类,执行对应的方法
invokeBeanFactoryPostProcessors(beanFactory);
//注册几个BeanPostProcessor
registerBeanPostProcessors(beanFactory);
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();
//实例化非懒加载的bean,这里调用了BeanPostProcessor对应方法
finishBeanFactoryInitialization(beanFactory);
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();
}
}
}
首先我们先了解几个重要的接口,上面的代码才看得懂
1.BeanFactoryPostProcessor接口
作用:可以获取到目前为止beanFactory里面的数据,进行想要的解析
调用时机:refresh方法中的invokeBeanFactoryPostProcessors方法
定义如下:
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
2.BeanDefinitionRegistryPostProcessor接口(BeanFactoryPostProcessor的子接口)
作用:可以往spring容器里面注册BeanDefinition,创建bean
调用时机:refresh方法中的invokeBeanFactoryPostProcessors方法
定义如下:
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
3.BeanPostProcessor接口
作用:可以根据spring创建出来的bean,进行相关处理,再返回真实的bean
调用时机:反射创建完bean,属性注入后调用(此时还未调用各种init方法),即refresh方法中的finishBeanFactoryInitialization方法
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
此时对spring的大概流程调用是否有系统的了解了呢?
实际上我们解析@Configuration/@Import/@Bean等等标签是通过ConfigurationClassPostProcessor这个类去解析的,它是实现了BeanDefinitionRegistryPostProcessor接口,所以它的调用时机是在refresh方法中的invokeBeanFactoryPostProcessors方法
接下来有空再写~~~欢迎各位指正哦~