Spring 使用 Demo
public class DemoApplicationTest { public static void main(String[] args) { // 创建容器 ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class); // 获取 UserService 对象 UserService userService = applicationContext.getBean(UserService.class); // 执行 test 方法 userService.test(); } } @Configuration @Import(UserService.class) class AppConfig { } // UserSerivce 类 @Service public class UserService { public String test() { return "test"; } }
Spring 的启动过程以及方法入口
// 入口方法 AbstractApplicationContext#refresh() // 1. 刷新前的预处理工作 prepareRefresh(); // 2. 获取 BeanFactory ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 3. BeanFactory 预处理工作 prepareBeanFactory(beanFactory); // 4.BeanFactory 完成后进行的后置处理工作 postProcessBeanFactory(beanFactory); // 5. 执行 BeanFactoryPostProcessors invokeBeanFactoryPostProcessors(beanFactory); // 6. 注册 Bean 后置处理器 [intercept bean creation.] registerBeanPostProcessors(beanFactory); // 7. 初始化 MessageSource 组件(做国际化功能, 消息绑定,消息解析) initMessageSource(); // 8. 初始化事件派发器 initApplicationEventMulticaster(); // 9. 留给自容器(子类) onRefresh(); // 10. 给容器中将所有的项目中的 ApplicationListener 注册进来 registerListeners(); // 11. 初始化所有的非懒加载单实例Bean finishBeanFactoryInitialization(beanFactory); // 12. 执行Spring容器的生命周期(启动)和发布事件 finishRefresh();
Spring 启动过程描述
1. prepareRefresh() 刷新前的预处理工作
- 记录启动事件
- 允许子容器可以设置一些属性到 environment
- 检查衍生属性是否合法,是否包含必须的属性
- 实现代码如下:
protected void prepareRefresh() { // 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. // 1. 初始化一些属性设置, 允许子容器设置一些内容到 environment 中 initPropertySources(); // Validate that all properties marked as required are resolvable: // see ConfigurablePropertyResolver#setRequiredProperties // 2. 校验必填属性是否有值 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... // 3. 创建集合保存容器的一些早期事件 this.earlyApplicationEvents = new LinkedHashSet<>(); }
- 在Spring MVC 中对
initPropertySources
方法做了实现,将 Servlet 容器相关的信息放到了 environment 中,实现如下
//Spring MVC 的 GenericWebApplicationContext 类 protected void initPropertySources() { ConfigurableEnvironment env = getEnvironment(); if (env instanceof ConfigurableWebEnvironment) { ((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, null); } }
2. obtainFreshBeanFactory() 获取 BeanFactory 对象
- 刷新 BeanFactory
// 创建 BeanFactory 是在 AbstractApplicationContext 的无参构造方法中初始化 // GenericApplicationContext 类 public GenericApplicationContext() { this.beanFactory = new DefaultListableBeanFactory(); } // AnnotationConfigApplicationContext 类的定义签名和继承关系 public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry { // ...... }
- 调用
obtainFreshBeanFactory
方法返回 BeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { // 1. 刷新【创建】BeanFactory refreshBeanFactory(); // 2. 返回 BeanFactory return getBeanFactory(); }
- 注意:
refreshBeanFactory
方法有两个实现类AbstractRefreshableApplicationContext
,GenericApplicationContext
我们当前创建容器是你用的AnnotationConfigApplicationContext
类。它是GenericApplicationContext
的子类,所以当前容器 不支持重复刷新。如果需要重复刷新的话可以选择AnnotationConfigWebApplicationContext
类。
AnnotationConfigApplicationContext application =new AnnotationConfigApplicationContext(); application.register(ApplicationConfig.class); application.refresh(); application.refresh(); //报错: IllegalStateException
3. prepareBeanFactory(beanFactory) 准备 BeanFactory
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 1. 设置 BeanFactory 的类加载器,支持表达式解析器 .... beanFactory.setBeanClassLoader(getClassLoader()); // el 解析器 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); // 默认类型转换器 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // 2. 添加部分的 BeanFactory 的 BeanPostProcessor [ApplicationContextAwareProcessor] // Bean 后置处理器 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 3. 设置忽略的自动装配的接口 EnvironmentAware 、EmbeddedValueResolverAware // 如果实现了这些接口重写的 set 方法,那么 Spring 就不会去自动装配 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); // 4. 注册可以解析的自动装配,我们能够直接在任何组件中自动注入: // BeanFactory、ResourceLoader、ApplicationEventPublisher、 ApplicationContext beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // 5. 添加 BeanPostProcessor 【ApplicationListenerDetector】 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // 6. 添加编译时的 AspectJ 支持 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())); } // 7. 给 BeanFactory 中注册一些能用的组件: // environment 【ConfigurableEnvironment】 // systemProperties 【Map<String, Object>】 // systemEnvironment【Map<String, Object>】 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()); } }