spring-源码-AnnotationConfigApplicationContext-创建分析-6

tech2026-04-10  2

文章目录

前言调用refresh()调用 obtainFreshBeanFactoryrefreshBeanFactory();getBeanFactory(); 调用 prepareBeanFactory()registerSingletonsuper.registerSingletonaddSingleton updateManualSingletonNamesclearByTypeCache 扩展阅读表达式语言解析器registerSingletonregisterResolvableDependencygetEnvironment

前言

本文仅分析 obtainFreshBeanFactory() 这和prepareBeanFactory()方法,其他初始化参考系列文章~~

调用refresh()

public AnnotationConfigApplicationContext(Class<?>... componentClasses) { //刷新容器,需要注意的是 refresh() 是父类的方法 refresh(); } 实现 @Override public void refresh() throws BeansException, IllegalStateException { // 先加个锁. 防止这个方法还没执行完,其他的也开始搞了. synchronized (this.startupShutdownMonitor) { //个方法是做准备工作的,记录容器的启动时间、标记“已启动”状态、 prepareRefresh(); // 获取 beanFactory ,也就是说获取的是 DefaultListableBeanFactory ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //可以说是对 DefaultListableBeanFactory 进行一些初始化的配置 prepareBeanFactory(beanFactory); try { //beanFactory 的后置处理器,在BeanFactory初始化之后执行的,这个后置处理是空的,需要子类去实现 postProcessBeanFactory(beanFactory); // BeanFactory 的后置处理器,在 BeanFactory 初始化之后执行的 invokeBeanFactoryPostProcessors(beanFactory); // 注册BeanPostProcessor(Bean的后置处理器),用于拦截bean创建过程 registerBeanPostProcessors(beanFactory); // 初始化MessageSource组件(做国际化功能;消息绑定,消息解析) initMessageSource(); // 初始化事件派发器 initApplicationEventMulticaster(); // 空方法,可以用于子类实现在容器刷新时自定义逻辑, onRefresh(); // 注册时间监听器,将所有项目里面的ApplicationListener注册到容器中来 registerListeners(); // 实例化所有的单例Bean,懒加载除外,也就是说被修饰过@Lazy的除外 finishBeanFactoryInitialization(beanFactory); // 完成BeanFactory的初始化创建工作,IOC容器就创建完成; finishRefresh(); } catch (BeansException 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(); } } }

调用 obtainFreshBeanFactory

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { // 刷新 BeanFactory // 这个方法是抽象方法,由子类去实现, // 1. 而当前子类是 AnnotationConfigApplicationContext,当前子类没有这个方法,子类继承了 GenericApplicationContext // 2. 那就调用 GenericApplicationContext refreshBeanFactory(); //返回了一个在创建时候的一个工厂,在创建的时候是 创建了 DefaultListableBeanFactory return getBeanFactory(); }

refreshBeanFactory();

protected final void refreshBeanFactory() throws IllegalStateException { // cas 操作 // 比较并替换,也就说这个方法只能调用一遍,为啥呢? // 比较并替换 比较的值为 false , 替换的值 true, 第一次 // 二次调用的时候 如果还是 这样就会返回 false 表示替换失败,而替换失败后则会抛出异常 // 表示不允许二次刷新 if (!this.refreshed.compareAndSet(false, true)) { throw new IllegalStateException( "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once"); } //设置了一个序列化ID this.beanFactory.setSerializationId(getId()); }

getBeanFactory();

这里就是返回 BeanFactory 就不细说了

调用 prepareBeanFactory()

通过方法名判断,准备 BeanFactory,简单来说就是 做一些初始化 BeanFactory 的操作

private static final boolean shouldIgnoreSpel = SpringProperties.getFlag("spring.spel.ignore"); protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 设置 DefaultListableBeanFactory的 加载器 beanFactory.setBeanClassLoader(getClassLoader()); // 通过在 spring.properties 配置是否开启 表达式语言解析器,默认是(不忽略) if (!shouldIgnoreSpel) { beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); } //设置属性编辑 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // 添加一个 PostProcessor 也就是 ApplicationContextAwareProcessor, beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 忽略自动装配的接口, // 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); // 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); // 注册早期的后处理器以将内部bean检测为ApplicationListeners。 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // Detect a LoadTimeWeaver and prepare for weaving, if found. if (!IN_NATIVE_IMAGE && 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())); } // 如果 beanFactory 已经存在则不会进行 if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { // 注入环境属性, beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } // 如果 beanFactory 已经存在则不会进行 if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { // 注入 系统的属性 beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } // 如果 beanFactory 已经存在则不会进行注册 if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { // 注入 系统环境属性 beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }

registerSingleton

注册单例Bean

public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException { // 注册单例的Bean,此处注册的Bean 是没有spring 生命周期的,仅仅是将 beanName 和bean 做一个映射放入到缓存中 super.registerSingleton(beanName, singletonObject); // updateManualSingletonNames( set -> set.add(beanName), // 将name 添加到 set集合中 // beanDefinitionMap 判断这 个beanName // 不存在则 是true // 存在则为 false.. set -> !this.beanDefinitionMap.containsKey(beanName) ); // 清除缓存 clearByTypeCache(); }

super.registerSingleton

public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException { // 进行加锁,保证线程安全,假设在多线程操作下, // 如果没有加锁,可能正准备添加,结果第二线程也过来了..去获取了.获取不到也去添加.. synchronized (this.singletonObjects) { // 先去获取 Object oldObject = this.singletonObjects.get(beanName); // 如果存在抛出异常 if (oldObject != null) { throw new IllegalStateException("Could not register object [" + singletonObject + "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound"); } // 去添加 addSingleton(beanName, singletonObject); } }

addSingleton

protected void addSingleton(String beanName, Object singletonObject) { // 这里为什么还会被加一把锁,是因为有可能这个方法是单独被调用,所以加了一把锁 synchronized (this.singletonObjects) { // 添加到单例 Map中 this.singletonObjects.put(beanName, singletonObject); // 从 三级缓存删除,后面文章会说明 this.singletonFactories.remove(beanName); // 从 二级缓存删除,后面文章会说明 this.earlySingletonObjects.remove(beanName); // 将beanName放入到集合中 this.registeredSingletons.add(beanName); } }

updateManualSingletonNames

// action 执行的 add 方法 // condition 执行的是 !this.beanDefinitionMap.containsKey(beanName) private void updateManualSingletonNames(Consumer<Set<String>> action, Predicate<Set<String>> condition) { // 判断容器是否已经开始创建了 if (hasBeanCreationStarted()) { //注册过程需要保证数据的一致性,所有需要加锁同步 synchronized (this.beanDefinitionMap) { // 根据给定的 beanName 判断 beanDefinitionMap 中是否存在,如果存在直接跳过 if (condition.test(this.manualSingletonNames)) { // 将 手动注册 Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames); // 将添加到 updatedSingletons 集合中 action.accept(updatedSingletons); this.manualSingletonNames = updatedSingletons; } } } // 如果进入else就代表了仍处于启动注册阶段 else { // 根据给定的 beanName 判断 beanDefinitionMap 中是否存在,如果存在直接跳过 if (condition.test(this.manualSingletonNames)) { action.accept(this.manualSingletonNames); } } }

clearByTypeCache

这里暂时不用管,是因为我们这些方法里面还没涉及到…

private void clearByTypeCache() { this.allBeanNamesByType.clear(); this.singletonBeanNamesByType.clear(); }

扩展阅读

表达式语言解析器

在 resources 下面定义一个spring.proerties

spring.spel.ignore=true 可以进行输出一下,其原理大家可以看看这边就不贴了 private static void properties() { System.out.println(SpringProperties.getFlag("spring.spel.ignore")); }

registerSingleton

注册单例Bean,需要注意的是,此时注册的Bean 是没有 spring生命周期的,为啥这么说呢,是因为只要是 手动注册 都是对象是直接创建好的。是直接放到了 spring 一级缓存中

private static void prepareBeanFactory() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(PrepareRefreshContext.class); DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getBeanFactory(); // 注册 单体对象 beanFactory.registerSingleton("user",new User()); // 从容器中获取,这里我不会去将 getBean.. 阶段的代码. 因为太复杂了.. 但是我可以明确的告诉 // doGetBean(beanName)方法体中第二行代码就是--> getSingleton(beanName) 这样就直接去 取到了,所以不会有 spring的 各种回调~~~ User bean = beanFactory.getBean(User.class); System.out.println(bean); }

而且只能注册一次,注册第二次则会失败…也就说相同的注册会失败…

private static void prepareBeanFactory() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(PrepareRefreshContext.class); DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getBeanFactory(); // 注册 单体对象 beanFactory.registerSingleton("user",new User()); // 二次注册一定出错 beanFactory.registerSingleton("user",new User()); }

如果 registerSingleton 和 beanDefinitionMap 如果 beanDefinitionMap 有了也不会进行注册…

private static void prepareBeanFactory() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(PrepareRefreshContext.class); DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getBeanFactory(); beanFactory.registerBeanDefinition("user", BeanDefinitionBuilder.genericBeanDefinition(User.class).getBeanDefinition()); // 这里注册单体Bean 并不会注册到容器中,因为在注册前会先 去校验 BeanDefinitionMap 中做一个校验 beanFactory.registerSingleton("user",new User()); User bean = beanFactory.getBean(User.class); System.out.println(bean); }

registerResolvableDependency

用相应的自动装配值注册一个特殊的依赖类型。且只能注册一次,为什么要这么做呢?在Spring自动装配的时候如果一个接口有多个实现类,并且都已经放到IOC中去了,那么自动装配的时候就会出异常,因为spring不知道把哪个实现类注入进去,这里不涉及@Primary的讲解,那有没有什么办法就是如果是这个类型的我就指定实现类来进行自动装配呢?registerResolvableDependency()这个方法的作用就是干这个的…

也就是说不能通过依赖查找,为什么?因为你注册的时候,spring 就压根没告诉你名字你怎么做依赖查找呀…

只能通过依赖注入的方式进行注入,简单来说只能通过类型进行注入…

@ComponentScan @Configuration public class ObtainFreshBeanFactoryContext { @Autowired private People people; public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(ObtainFreshBeanFactoryContext.class); registerResolvableDependency(context); context.refresh(); // 获取Bean ObtainFreshBeanFactoryContext bean = context.getBean(ObtainFreshBeanFactoryContext.class); // 获取我们使用 registerResolvableDependency 添加的Bean System.out.println(bean.people); } private static void registerResolvableDependency(AnnotationConfigApplicationContext context) { context.getBeanFactory().registerResolvableDependency(People.class, new ZhangSan()); } } interface People { }; class ZhangSan implements People { } class WangWu implements People { }

getEnvironment

这里帮我们注册 单体对象… 我们可以去获取出来看看,至于API 可以自己了解一下 public static void getEnvironment() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(PrepareRefreshContext.class); context.refresh(); StandardEnvironment environment = (StandardEnvironment) context.getBean("environment"); System.out.println(environment.getClass()); Properties systemProperties = (Properties) context.getBean("systemProperties"); System.out.println(systemProperties.getClass()); Object systemEnvironment = context.getBean("systemEnvironment"); System.out.println(systemEnvironment.getClass()); }
最新回复(0)