微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Spring源码-beanFactory的准备工作

AbstractApplicationContext类refresh方法调用obtainFreshbeanfactory加载BeanDiFinition到beanfactory中,接下来执行beanfactory的准备工作为下面的执行作铺垫。
preparebeanfactory方法beanfactory做准备工作:

protected void preparebeanfactory(ConfigurableListablebeanfactory beanfactory) {

	// 设置beanfactory的classloader为当前context的classloader
	beanfactory.setBeanClassLoader(getClassLoader());
	// 设置beanfactory的表达式语言处理器
	beanfactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanfactory.getBeanClassLoader()));
	// 为beanfactory增加一个认的propertyeditor,这个主要是对bean的属性等设置管理的一个工具类
	beanfactory.addpropertyeditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

	// 添加beanPostProcessor,ApplicationContextAwareProcessor此类用来完成某些Aware对象的注入
	beanfactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
	// 设置要忽略自动装配的接口,这些接口的实现是由容器通过set方法进行注入的,
	// 所以在使用autowire进行注入的时候需要将这些接口进行忽略
	beanfactory.ignoreDependencyInterface(EnvironmentAware.class);
	beanfactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
	beanfactory.ignoreDependencyInterface(ResourceLoaderAware.class);
	beanfactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
	beanfactory.ignoreDependencyInterface(MessageSourceAware.class);
	beanfactory.ignoreDependencyInterface(ApplicationContextAware.class);


	// 设置几个自动装配的特殊规则,当在进行ioc初始化的如果有多个实现,那么就使用指定的对象进行注入
	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.
	beanfactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

	// 增加对AspectJ的支持,在java中织入分为三种方式,分为编译器织入,类加载器织入,运行期织入,编译器织入是指在java编译器,采用特殊的编译器,将切面织入到java类中,
	// 而类加载期织入则指通过特殊的类加载器,在类字节码加载到JVM时,织入切面,运行期织入则是采用cglib和jdk进行切面的织入
	// aspectj提供了两种织入方式,第一种是通过特殊编译器,在编译器,将aspectj语言编写的切面类织入到java类中,第二种是类加载期织入,就是下面的load time weaving
	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()));
	}

	// 注册系统认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());
	}
}

propertyeditor例子:

People.class

import java.util.Date;

public class People {
	private String name;

	private Date birthday;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}


	@Override
	public String toString() {
		return "People{" +
				"name='" + name + '\'' +
				", birthday=" + birthday +
				'}';
	}
}

Datepropertyeditor.class

import java.beans.propertyeditorSupport;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Datepropertyeditor extends propertyeditorSupport {

	@Override
	public void setAsText(String text) throws IllegalArgumentException {
		SimpleDateFormat format = new SimpleDateFormat("YYYY-MM-DD");
		try {
			Date date = format.parse(text);
			setValue(date);
		} catch (ParseException e) {
			e.printstacktrace();
		}
	}
}

DatepropertyeditorRegistrar.class

import org.springframework.beans.propertyeditorRegistrar;
import org.springframework.beans.propertyeditorRegistry;

import java.util.Date;

public class DatepropertyeditorRegistrar implements propertyeditorRegistrar {
	@Override
	public void registerCustomEditors(propertyeditorRegistry registry) {
		registry.registerCustomEditor(Date.class, new Datepropertyeditor());
	}
}

app.xml

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
	<property name="propertyeditorRegistrars">
		<list>
			<ref bean="custompropertyeditorRegistrar"/>
		</list>
	</property>
</bean>

<bean id="custompropertyeditorRegistrar"
	  class="xml.DatepropertyeditorRegistrar"/>

测试:

ApplicationContext applicationContext = new ClasspathXmlApplicationContext("classpath:app.xml");
People people = applicationContext.getBean(People.class);
System.out.println(people);

输出

ApplicationContextAwareProcessor.class

class ApplicationContextAwareProcessor implements BeanPostProcessor {

	private final ConfigurableApplicationContext applicationContext;

	private final StringValueResolver embeddedValueResolver;


	/**
	 * Create a new ApplicationContextAwareProcessor for the given context.
	 */
	public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
		this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getbeanfactory());
	}


	@Override
	@Nullable
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
				bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
				bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware ||
				bean instanceof ApplicationStartupAware)) {
			return bean;
		}

		AccessControlContext acc = null;

		if (System.getSecurityManager() != null) {
			acc = this.applicationContext.getbeanfactory().getAccessControlContext();
		}

		if (acc != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareInterfaces(bean);
				return null;
			}, acc);
		}
		else {
			invokeAwareInterfaces(bean);
		}

		return bean;
	}

	private void invokeAwareInterfaces(Object bean) {
		if (bean instanceof EnvironmentAware) {
			((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
		}
		if (bean instanceof EmbeddedValueResolverAware) {
			((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
		}
		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 ApplicationStartupAware) {
			((ApplicationStartupAware) bean).setApplicationStartup(this.applicationContext.getApplicationStartup());
		}
		if (bean instanceof ApplicationContextAware) {
			((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
		}
	}

}

ApplicationContextAwareProcessor实现了BeanPostProcessor接口,初始化bean之前执行postProcessBeforeInitialization方法,将实现了以下Aware接口的类注入Aware实现类:

EnvironmentAware
EmbeddedValueResolverAware
ResourceLoaderAware
ApplicationEventPublisherAware
MessageSourceAware
ApplicationStartupAware
ApplicationContextAware

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐