容器的功能扩展(二)功能扩展

进入函数prepareBeanFactory前,Spring已经完成了对配置的解析,而ApplicationContext在功能上的扩展也由此展开。

	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());
		//设置beanFactory的表达式语言处理器,Spring3增加了表达式语言的支持,
		//默认可以使用#{bean.xxx}的形式来调用相关属性值
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
		//为beanFactory增加了一个默认的propertyEditor,这个主要是对bean的属性等设置管理的一个工具
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		/*
		 * 添加BeanPostProcessor,
		 */
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		//设置了几个忽略自动装配的接口
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
		beanFactory.ignoreDependencyInterface(EnvironmentAware.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);

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		//增加对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()));
		}

		// Register default environment beans.
		//添加默认的系统环境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.增加SPEL语言支持

Spring表达式语言全称为“Spring Expression Language”,缩写为“SpEL”,类似于Struts 2x中使用的OGNL语言,SpEL是单独模块,只依赖于core模块,不依赖于其他模块,可以单独使用。

SpEL使用#{...}作为定界符,所有在大框号中的字符都将被认为是SpEL,使用格式如下:

	
	
	
	  
	  
	  
	  
	

上面只是列举了其中最简单的使用方式,SpEL功能非常强大,使用好可以大大提高开发效率。

在源码中通过代码beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver()),注册语言解析器,就可以对SpEL进行解析了,那么之后是在什么地方调用这个解析器的呢?

之前说beanFactory中说过Spring在bean进行初始化的时候会有属性填充的一步,而在这一步中Spring会调用AbstractAutowireCapabelBeanFactory类的applyPropertyValues来进行属性值得解析。同时这个步骤中一般通过AbstractBeanFactory中的evaluateBeanDefinitionString方法进行SpEL解析:

	protected Object evaluateBeanDefinitionString(String value, BeanDefinition beanDefinition) {
		if (this.beanExpressionResolver == null) {
			return value;
		}
		Scope scope = (beanDefinition != null ? getRegisteredScope(beanDefinition.getScope()) : null);
		return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope));
	}

当调用这个方法时会判断是否有语言解析器,如果存在则调用语言解析器,解析的过程在Spring的expression包里。

2.添加ApplicationContextAwareProcessor处理器

beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));其实主要目的就是注册个BeanPostProcessor,而真正的逻辑实现还是在ApplicationContextAwareProcessor中。

ApplicationContextAwareProcessor实现了BeanPostProcessor接口,我们看下之前说过的东西,在bean实例化的时候,也就是Spring激活bean的init-method的前后,会调用BeanProcessor的postProcessBeforeInitialization方法和postProcessAfterInitialization方法。同样,对于ApplicationContextAwareProcessor也有这两个方法。

对于postProcessAfterInitialization方法,在ApplicationContextAwareProcessor中并没有做过多处理。

	public Object postProcessAfterInitialization(Object bean, String beanName) {
		return bean;
	}

重点看下 postProcessBeforeInitialization方法:

	public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
		AccessControlContext acc = null;

		if (System.getSecurityManager() != null &&
				(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
						bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
						bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
		}

		if (acc != null) {
			AccessController.doPrivileged(new PrivilegedAction() {
				public Object run() {
					invokeAwareInterfaces(bean);
					return null;
				}
			}, acc);
		}
		else {
			invokeAwareInterfaces(bean);
		}

		return bean;
	}

	private void invokeAwareInterfaces(Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof EnvironmentAware) {
				((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
			}
			if (bean instanceof EmbeddedValueResolverAware) {
				((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(
						new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
			}
			if (bean instanceof ResourceLoaderAware) {
				((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
			}
			if (bean instanceof ApplicationEventPublisherAware) {
				((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
			}
			if (bean instanceof MessageSourceAware) {
				((MessageSourceAware) bean).setMessageSource(this.applicationContext);
			}
			if (bean instanceof ApplicationContextAware) {
				((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
			}
		}
	}

postProcessBeforeInitialization方法中调用了invokeAwareInterfaces。从invokeAwareInterfaces方法中,我们可以看出来,实现这些Aware接口的bean在被初始化之后,可以取得一些对应的资源。

3.设置忽略依赖

Spring将ApplicationContextAwareProcessor注册后,在invokeAwareInterfaces方法中间调用的Aware类已经不是普通的bean了,如ResourceLoaderAware,ApplicationEventPublisherAware等,那么当然需要在Spring做bean的依赖注入的时候忽略它们。而ignoreDependencyInterface的作用正是如此。

		//设置了几个忽略自动装配的接口
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);

4.注册依赖

Spring中有忽略依赖的功能,也有注册依赖的功能。

		//设置了几个自动装配的特殊 规则
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

当注册了依赖解析后,例如当注册了对BeanFactory.class的解析后,当bean的属性注入的时候,一旦检测到属性为BeanFactory类型便会将beanFactory的实例注入进去。

可能有些朋友有些迷糊,为什么刚刚实现了接口又忽略依赖注入,刚忽略接口的依赖注入,下面又增加了注册依赖的功能?

因为在Spring加载bean的时候,还会将实现的接口依赖进去,因为是单例模式的,这些接口已经在spring的其他模块做了依赖处理,在此不需要重复依赖。

你可能感兴趣的:(spring源码解析)