Spring5源码之四——refresh方法之prepareBeanFactory()

书接前文:Spring源码之三——refresh方法之obtainFreshBeanFactory()

        接下来,我们来看一下refresh方法中的prepareBeanFactory()方法,此方法主要用来配置工厂的标准上下文特征,例如上下文的 ClassLoader 和后处理器。话不多说,直接看具体实现。

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 设置用于加载 bean 类的类加载器。 默认是线程上下文类加载器
		beanFactory.setBeanClassLoader(getClassLoader());
		//指定 bean 定义值中表达式的解析策略
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		//添加要应用于所有 bean 创建过程的 PropertyEditorRegistrar
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
		// 添加一个新的 BeanPostProcessor,它将应用于此工厂创建的 bean。 在出厂配置期间调用。
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		//忽略给定的自动装配依赖的EnvironmentAware接口
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		//忽略给定的自动装配依赖的EmbeddedValueResolverAware接口
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		//忽略给定的自动装配依赖的ResourceLoaderAware接口
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		//忽略给定的自动装配依赖的ApplicationEventPublisherAware接口
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		//忽略给定的自动装配依赖的MessageSourceAware接口
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		//忽略给定的自动装配依赖的ApplicationContextAware接口
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
		//使用相应的自动装配值注册一个BeanFactory依赖类型
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		//使用相应的自动装配值注册一个ResourceLoader依赖类型
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		//使用相应的自动装配值注册一个ApplicationEventPublisher依赖类型
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		//使用相应的自动装配值注册一个ApplicationContext依赖类型
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		//添加一个新的 BeanPostProcessor,它将应用于此工厂创建的 bean。 在出厂配置期间调用,为检测ApplicationListeners内部bean
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		//这个 bean 工厂是否包含具有给定名称的 bean 定义或外部注册的单例实例?如果给定的名称是别名,它将被转换回相应的规范 bean 名称。如果这个工厂是分层的,如果在这个工厂实例中找不到 bean,将询问任何父工厂。
		//如果找到与给定名称匹配的 bean 定义或单例实例,则无论命名的 bean 定义是具体的还是抽象的、惰性的还是急切的、范围内的,此方法都将返回true 。 因此,请注意,此方法的true返回值并不一定表示getBean将能够获得同名的实例。
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			//指定用于类型匹配目的的临时类加载器。 默认为 none,只需使用标准 bean ClassLoader
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
		
		//根据环境或系统bean注册成单例
		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());
		}
	}

可能看了以上的实现,觉得似懂非懂,下面我挑选一些主要来解释下。

(1)设置bean的类加载器,这里没啥好说的。要想后续加载一个bean,肯定需要先获取bean的类加载器。

beanFactory.setBeanClassLoader(getClassLoader());

public class DefaultResourceLoader implements ResourceLoader {
    //省略部分代码......

    @Override
	@Nullable
	public ClassLoader getClassLoader() {
		return (this.classLoader != null ? this.classLoader : ClassUtils.getDefaultClassLoader());
	}
}

(2)StandardBeanExpressionResolver对象,用于解析形如 #{...}的SpEL表达式,这是一种比JSP中EL更高级的表达式。比如我们通常在application.xml中配置一个变量,在java中使用 @Value("#{表达式}")引用此变量。

beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));

(3)ResourceEditorRegistrar类,主要用于注册用户自定义的PropertyEditor实现类。

beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

(4)addBeanPostProcessor方法,添加一个ApplicationContextAwareProcessor的实例化对象到bean后置处理器(即:List<BeanPostProcessor> beanPostProcessors)中。接着,忽略给定接口实现类是忽略指定接口(UserAwre)的set方法的自动装配

        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

        //忽略给定的自动装配依赖的EnvironmentAware接口
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		//忽略给定的自动装配依赖的EmbeddedValueResolverAware接口
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		//忽略给定的自动装配依赖的ResourceLoaderAware接口
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		//忽略给定的自动装配依赖的ApplicationEventPublisherAware接口
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		//忽略给定的自动装配依赖的MessageSourceAware接口
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		//忽略给定的自动装配依赖的ApplicationContextAware接口
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

(5)为何要注册如下几个bean呢,是因为它们是spring容器初始化需要用到的内部bean,不出现在配置文件中,所以此处需要spring自行注册。

	    //使用相应的自动装配值注册一个BeanFactory依赖类型
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		//使用相应的自动装配值注册一个ResourceLoader依赖类型
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		//使用相应的自动装配值注册一个ApplicationEventPublisher依赖类型
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		//使用相应的自动装配值注册一个ApplicationContext依赖类型
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

(6)添加bean的后置处理器。

beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

(7)  判断容器中存在名为"loadTimeWeaver"的bean,如果有则则添加一个作用域为loadTimeWeaver(代码织入)的后置处理器,在后续AOP解析中详细讲解,此处略。

    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			//指定用于类型匹配目的的临时类加载器。 默认为 none,只需使用标准 bean ClassLoader
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

(8)判断容器中存在名为"environment"、“systemProperties”、”systemEnvironment”的bean,如果有则注册对应的单例bean。

        //根据环境或系统bean注册成单例
		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());
		}

        prepareBeanFactory()方法,至此结束。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大鹏爷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值