zoukankan      html  css  js  c++  java
  • Spring IOC 初始化刷新流程三:prepareBeanFactory(beanFactory)

    Spring IOC 初始化刷新流程:https://www.cnblogs.com/jhxxb/p/13609289.html

    这一步主要是配置工厂的标准上下文特征

    方法源码

    public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
        protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
            // Tell the internal bean factory to use the context's class loader etc.
            // 设置 beanFactory 的 classLoader 为当前 context 的 classLoader
            beanFactory.setBeanClassLoader(getClassLoader());
            // 设置 EL 表达式解析器(Bean 初始化完成后填充属性时会用到)
            // spring3 增加了表达式语言的支持,默认可以使用 #{bean.xxx} 的形式来调用相关属性值
            beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
            // 设置属性注册解析器 PropertyEditor,这个主要是对 bean 的属性等设置管理的一个工具
            beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    
            // Configure the bean factory with context callbacks.
            // 将当前的 ApplicationContext 对象交给 ApplicationContextAwareProcessor 类来处理,从而在 Aware 接口实现类中注入 applicationContext 等
            // 添加了一个处理 Aware 相关接口的 beanPostProcessor 扩展,主要是使用 beanPostProcessor 的 postProcessBeforeInitialization() 前置处理方法实现 Aware 相关接口的功能
            // 类似的还有 ResourceLoaderAware、ServletContextAware 等
            beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
            // 下面是忽略的自动装配(也就是实现了这些接口的 Bean,不要 Autowired 自动装配了)
            // 默认只有 BeanFactoryAware 被忽略,所以其它的需要自行设置
            // 因为 ApplicationContextAwareProcessor 把这 5 个接口的实现工作做了,所以这里就直接忽略掉
            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 的类,就注册 beanFactory
            // 如果是 ResourceLoader、ApplicationEventPublisher、ApplicationContext 等,就注入当前对象 this(applicationContext对象)
            // 此处 registerResolvableDependency() 会把它们加入到 DefaultListableBeanFactory 的 resolvableDependencies 字段里面缓存,供后面处理依赖注入的时候使用,DefaultListableBeanFactory#resolveDependency 处理依赖关系
            // 这也是为什么我们可以通过依赖注入的方式直接注入这几个对象,比如 ApplicationContext 可以直接依赖注入
            // 但是需要注意的是:这些 Bean,Spring 的 IOC 容器里其实是没有的。beanFactory.getBeanDefinitionNames() 和 beanFactory.getSingletonNames() 都是找不到它们的,特别需要理解这一点
            beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
            beanFactory.registerResolvableDependency(ResourceLoader.class, this);
            beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
            beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    
            // Register early post-processor for detecting inner beans as ApplicationListeners.
            // 注册这个 Bean 的后置处理器:在 Bean 初始化后检查是否实现了 ApplicationListener 接口
            // 是,则加入当前 applicationContext 的 applicationListeners 列表,这样后面广播事件也就方便了
            beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    
            // Detect a LoadTimeWeaver and prepare for weaving, if found.
            // 检查容器中是否包含名称为 loadTimeWeaver 的 bean,实际上是增加 Aspectj 的支持
            // AspectJ 采用编译期织入、类加载期织入两种方式进行切面的织入
            // 类加载期织入简称为 LTW(Load Time Weaving),通过特殊的类加载器来代理 JVM 默认的类加载器实现
            if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
                // 添加 Bean 后置处理器:LoadTimeWeaverAwareProcessor
                // 在 Bean 初始化之前检查 Bean 是否实现了 LoadTimeWeaverAware 接口,如果是,则进行加载时织入,即静态代理。
                beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
                // Set a temporary ClassLoader for type matching.
                beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
            }
    
            // Register default environment beans.
            // 注入一些其它信息的 bean,比如 environment、systemProperties、SystemEnvironment 等
            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());
            }
        }

    注:@Autowiredh 和 @Qualifier 一起使用时,@Qualifier 的值需保证容器里一定有,否则启动报错

    IOC 容器中没有 Bean,但是我们还是可以依赖注入的 Bean,registerResolvableDependency()

  • 相关阅读:
    zzuli2470: 迷宫
    zzuli2460: 楼上真的是签到题
    zzuli2460: 楼上真的是签到题
    洛谷P1044 :栈(卡特兰数)
    洛谷P1044 :栈(卡特兰数)
    洛谷P1056:排座椅(贪心)
    代码块地址
    tabBarItem动画
    vim Podfile
    webView进度条
  • 原文地址:https://www.cnblogs.com/jhxxb/p/13953664.html
Copyright © 2011-2022 走看看