Spring源码(二)-Context的创建(上)
来源:互联网 发布:索尼电视推荐 知乎 编辑:程序博客网 时间:2024/06/01 07:31
我们前一章介绍了spring的整体架构以及模块划分,也已经将代码导入ide中,那么接下来就要开始让人心动的Spring源码之旅了。
1、默认的Spring启动器
@SpringBootApplication@ComponentScan(basePackages = {"com"})public class SpringSourceApplication { public static void main(String[] args) { ApplicationContext ctx = SpringApplication.run(SpringSourceApplication.class, args); }}
该方法是Springboot的启动类
2、进入SpringApplication.java
public static ConfigurableApplicationContext run(Object source, String... args) { return run(new Object[] { source }, args);}
public static ConfigurableApplicationContext run(Object[] sources, String[] args) { return new SpringApplication(sources).run(args);}
这里创建了一个SpringApplication方法,执行run方法,返回一个ConfigurableApplicationContext,这只是一个接口而已,根据名称来看,这是一个可配置的应用程序上下文。
3、进入run方法
SpringApplication(sources)这个类的初始化就先不看,这里面调用了initialize()方法,主要完成了当前的运行环境,以及设置了ApplicationListener相关的东西,这里我们先不做分析,直接进入run方法。
public ConfigurableApplicationContext run(String... args) { //记录程序运行时间 StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; FailureAnalyzers analyzers = null; /** * 设置headless模式 * 在我们的例子中该属性会被设置为true,因为我们开发的是服务器程序, * 一般运行在没有显示器和键盘的环境。关于java中的headless模式 */ configureHeadlessProperty(); SpringApplicationRunListeners listeners = getRunListeners(args); listeners.starting(); try { ApplicationArguments applicationArguments = new DefaultApplicationArguments( args); ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); configureIgnoreBeanInfo(environment); bindToSpringApplication(environment); Banner printedBanner = printBanner(environment); /** * 它创建出来的是ConfigurableApplicationContext类的实例对象 *AnnotationConfigEmbeddedWebApplicationContext */ context = createApplicationContext(); analyzers = new FailureAnalyzers(context); /** * 该方法对context进行了预设置,设置了ResourceLoader和ClassLoader, * 并向bean工厂中添加了一个beanNameGenerator */ prepareContext(context, environment, listeners, applicationArguments, printedBanner); /** * prepareContext()已经做好了refresh上下文的基础准备工作 * spring对ApplicationContext进行了向下转型, * 转型后的类型为:AbstractApplicationContex,并调用了它的refresh()方法 * 详见方法内部实现 */ refreshContext(context); afterRefresh(context, applicationArguments); listeners.finished(context, null); stopWatch.stop(); if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass) .logStarted(getApplicationLog(), stopWatch); } return context; } catch (Throwable ex) { handleRunFailure(context, listeners, analyzers, ex); throw new IllegalStateException(ex); } }
try代码块中是我们最核心的功能,代码中也添加了一部分的注释。我们先看context的创建过程即进入到createApplicationContext()方法。
protected ConfigurableApplicationContext createApplicationContext() { Class<?> contextClass = this.applicationContextClass; if (contextClass == null) { try { switch (this.webApplicationType) { case SERVLET: //此处采用反射获取WebApplicationContext contextClass = Class.forName(DEFAULT_WEB_CONTEXT_CLASS); break; case REACTIVE: contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS); break; default: contextClass = Class.forName(DEFAULT_CONTEXT_CLASS); } } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Unable create a default ApplicationContext, " + "please specify an ApplicationContextClass", ex); } } return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);}
DEFAULT_WEB_CONTEXT_CLASS —>AnnotationConfigEmbeddedWebApplicationContext
接下来执行AnnotationConfigEmbeddedWebApplicationContext的构造方法
public AnnotationConfigEmbeddedWebApplicationContext() { this.reader = new AnnotatedBeanDefinitionReader(this); this.scanner = new ClassPathBeanDefinitionScanner(this); }
上面实例化了AnnotatedBeanDefinitionReader以及ClassPathBeanDefinitionScanner
实例化AnnotatedBeanDefinitionReader
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) { this(registry, getOrCreateEnvironment(registry)); }
接下来是调用
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); Assert.notNull(environment, "Environment must not be null"); this.registry = registry; this.conditionEvaluator = new ConditionEvaluator(registry, environment, null); AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); }
实例化 ConditionEvaluator,将其属性ConditionContextImpl赋值
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
具体实现如下:
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) { //获取beanfactory信息,Spring IOC的核心 DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry) if (beanFactory != null) { if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(4); if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); } if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor. if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)); } // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor. if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(); try { def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, AnnotationConfigUtils.class.getClassLoader())); } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex); } def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)); } if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME)); } if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME)); } return beanDefs; }
上面代码比较长,我们来分开解析
- 1、DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
由wrap就可以看出此处使用的是装饰器模式,registry包裹成一个指定的beanFactory
private static DefaultListableBeanFactory unwrapDefaultListableBeanFactory(BeanDefinitionRegistry registry) { if (registry instanceof DefaultListableBeanFactory) { return (DefaultListableBeanFactory) registry; } else if (registry instanceof GenericApplicationContext) { //此处 GenericApplicationContext构造函数初始化beanFactory为DefaultListableBeanFactory return ((GenericApplicationContext) registry).getDefaultListableBeanFactory(); } else { return null; }}
代码执行到registry instanceof GenericApplicationContext(通过类继承结构可得到),随后调用GenericApplicationContext#getDefaultListableBeanFactory()方法,GenericApplicationContext在构造方法中实例化了属性beanFactory的值为DefaultListableBeanFactory:
public GenericApplicationContext() { this.beanFactory = new DefaultListableBeanFactory(); }
其构造优先于AnnotationConfigEmbeddedWebApplicationContext构造方法执行。
以上获得了BeanFactory信息
代码的构建请参考 github
该地址有相应代码的注释
Spring源码分析
- 1、Spring源码(一)-Spring整体架构和环境搭建
- 2、Spring源码(二)-Context的创建(上)
- 3、Spring源码(三)-Context的创建(下)
- Spring源码(二)-Context的创建(上)
- Spring源码(三)-Context的创建(下)
- Spring创建对象的三种方法之二静态工厂创建(源码)
- Tomcat源码分析之Context的创建与启动分析
- Android深入理解Context(二)Activity和Service的Context创建过程
- Context 的创建时机
- Mybatis源码(二)之Spring整合mybatis创建SqlSession
- Spring的servlet context和application context
- 深入源码-jetty加载spring-context容器
- Spring5源码解析-Spring中的Context loader
- Spring源码(四)-bean的加载(上)
- Spring源码分析-配置文件的解析(二)
- Android Context 源码的理解
- <context:spring-configured/> 的作用
- <context:spring-configured/> 的作用
- <context:spring-configured/> 的作用
- spring 启动过程 各个application context 的创建过程(重要)
- rxJava的使用--Observable的创建及源码分析(二)
- 20个常用的正则表达式
- Hibernate.hbm.xml映射关系(一对一、一对多、多对多)
- spring boot导入xml配置
- 如何做一个Android开发(我认为)
- Spring源码(一)-Spring整体架构和环境搭建
- Spring源码(二)-Context的创建(上)
- CodeForces
- myeclipse优化
- 备忘录
- OpenJudge 2.6-1775 采药
- 静态链表的C++简单实现
- Spring源码(三)-Context的创建(下)
- Android之Handler
- 阿里的Java面试经验---二