Spring IOC:容器创建前的准备工作

1.环境搭建

基于注解形式配置spring
因为我是从spring官网下载了源码允许的,所以jar包省略不写了。

1.1新建配置类
@Configuration
@ComponentScan("com.st")
public class Appconfig {
}
1.2新建dao
@Repository
public class Indexdao implements ApplicationContextAware {
	private ApplicationContext applicationContext;
	public Indexdao() {
		System.out.println("construtor");
	}
	@PostConstruct
	public void init(){
		System.out.println("inint");
	}
	public void query() {
		System.out.println("12");
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
		System.out.println("ApplicationContext applicationContext");
	}
}
1.3新建测试类
public class Test {
	public static void main(String[] args) {
		//使用默认的构造方法一定要在最后refresh
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		context.register(Appconfig.class);
		//context.refresh();
		context.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());
		context.refresh();
		Indexdao indexdao = context.getBean(Indexdao.class);
		Indexdao indexdao1 = context.getBean(Indexdao.class);
		indexdao.query();
		System.out.println(indexdao.hashCode()+"-------"+indexdao1.hashCode());
	}
}

2.AnnotationConfigApplicationContext 创建对象的时候spring都干了什么?

2.1 AnnotationConfigApplicationContext默认构造方法
public AnnotationConfigApplicationContext() {
         /**
	 * 这个类是一个reader,一个读取器
	 * 读取一个被加了注释的bean
	 * 这个类在构造方法中实例化
	 */
	private final AnnotatedBeanDefinitionReader reader;
	/**
	 * 扫描器,扫描所有加了注解的bean
	 * 但是实际上我们扫描包不是用的scanner这个对象
	 * 是Spring自己new的一个ClassPathBeanDefinitionScanner
	 * 这里的scanner仅仅是为了让我们能从外部调用AnnotationConfigApplicationContext的scanner方法
	 * 同样是在构造方法中被实例化
	 */
	private final ClassPathBeanDefinitionScanner scanner;
	
	//这里的this为当前类也就是AnnotationConfigApplicationContext,所以这个类也可以当作一个BeanDefinitionRegistry
	this.reader = new AnnotatedBeanDefinitionReader(this);
	this.scanner = new ClassPathBeanDefinitionScanner(this);
	}
2.2 AnnotationConfigApplicationContext(Class<?>… annotatedClasses)构造方法

一般我们都会这么写,直接在构造方法中写入我们的配置类

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		//这里由于他有父类,故而会先调用父类的构造方法,然后才会调用自己的构造方法
		//在默认的构造方法中初始一个读取器和扫描器
		this();
		register(annotatedClasses);
		refresh();
	}
2.3 看一下AnnotatedBeanDefinitionReader都做了什么

跟进AnnotatedBeanDefinitionReader的构造方法

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
		//getOrCreateEnvironment()给当前的registry创建个环境
		this(registry, getOrCreateEnvironment(registry));
	}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		Assert.notNull(environment, "Environment must not be null");
		this.registry = registry;
		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
	//注册处理器,这里点进去
	AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
		//真正的注册
		registerAnnotationConfigProcessors(registry, null);
	}

就是这里提供的后置处理器为spring扫描注册bean提供了强大的支持

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {
		//返回beanFactory
		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				//AnnotationAwareOrderComparator 能解析@Order注解和Priority
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				//提供了延迟加载的功能
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
		//往BeanDefinitionMap中注册spring内部的基础类
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			//ConfigurationClassPostProcessor 实现的BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor 这个类很重要,之后会提到
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
		if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
		if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition();
			try {
				def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
						AnnotationConfigUtils.class.getClassLoader()));
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
			}
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
		}

		return beanDefs;
	}

此时beanFactory中就会插入这几个基础的工具类
在这里插入图片描述
registerPostProcessor()其实就是调用 DefaultListableBeanFactory的registerBeanDefinition()方法往容器的beanMap中加入当前的bean
BeanDefinitionHolder 和BeanDefinition没太大的区别就是存了BeanDefinition还有他的别名和beanName

private static BeanDefinitionHolder registerPostProcessor(
			BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

		definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		registry.registerBeanDefinition(beanName, definition);
		return new BeanDefinitionHolder(definition, beanName);
	}

调用

2.4简单介绍后置处理器的作用

后置处理器可以粗略的分为BeanPostProcessor和BeanFactoryPostProcessor
创建一个BeanPostProcessor

@Component
public class TestBeanPostProcessor implements BeanPostProcessor {
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if(beanName.equals("indexdao")){
			System.out.println("before process" );
		}
		return null;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if(beanName.equals("indexdao")){
			System.out.println("after process" );
		}
		return null;
	}
}

可以看到,在容器创建之后,调用了beanPostProcessor的before,after方法
这样spring使用后置处理器就可以在bean创建之前对bean进行一些特殊处理
在这里插入图片描述

2.5ClassPathBeanDefinitionScanner将指定包下的类通过一定规则过滤后 将Class 信息包装成 BeanDefinition 的形式注册到IOC容器中
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
		this(registry, true);
	}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
			Environment environment) {
		//registry instanceof ResourceLoader 当前的registry是AnnotationConfigApplicationContext实现了ResourceLoader 接口
		this(registry, useDefaultFilters, environment,
				(registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
	}

ResourceLoader 提供了默认的classpath:*/

public interface ResourceLoader {

	/** Pseudo URL prefix for loading from the class path: "classpath:" */
	String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;
	Resource getResource(String location);
	@Nullable
	ClassLoader getClassLoader();

}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
			Environment environment, @Nullable ResourceLoader resourceLoader) {

		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		this.registry = registry;
		//默认设置了使用
		if (useDefaultFilters) {
			registerDefaultFilters();
		}
		setEnvironment(environment);
		setResourceLoader(resourceLoader);
	}

registerDefaultFilters

protected void registerDefaultFilters() {
		this.includeFilters.add(new AnnotationTypeFilter(Component.class));
		ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
		try {
			this.includeFilters.add(new AnnotationTypeFilter(
					((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
			logger.debug("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
		}
		catch (ClassNotFoundException ex) {
			// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
		}
		try {
			this.includeFilters.add(new AnnotationTypeFilter(
					((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
			logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
		}
		catch (ClassNotFoundException ex) {
			// JSR-330 API not available - simply skip.
		}
	}

这里插入了扫描的基本信息如果配置了include 和exclude就会在这里设置进去
在这里插入图片描述

3.AbstractApplicationContext的refresh方法

3.1prepareRefresh初始化属性源(property,source配置)
protected void prepareRefresh() {
		//准备工作包括设置启动时间,是否激活标识位
		// Switch to active.
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);

		if (logger.isInfoEnabled()) {
			logger.info("Refreshing " + this);
		}

		// Initialize any placeholder property sources in the context environment.
		//留给子类实现的方法
		initPropertySources();

		// Validate that all properties marked as required are resolvable:
		// see ConfigurablePropertyResolver#setRequiredProperties
		getEnvironment().validateRequiredProperties();

		// Store pre-refresh ApplicationListeners...
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
			// Reset local application listeners to pre-refresh state.
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}
3.2 obtainFreshBeanFactory

利用注解的配置类这里很简单直接返回beanFactory,用web.xml会比较复杂

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}
3.3prepareBeanFactory(beanFactory)

准备工厂

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// Tell the internal bean factory to use the context's class loader etc.
		beanFactory.setBeanClassLoader(getClassLoader());
		//bean表达式解析器,能够获取bean中的属性
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		//对象与string类型的转换 <property red="dao">
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		//添加一个后置处理器
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		//添加自动注入忽略的列表,继承以下类自动注入时会忽略
		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);

		// Register early post-processor for detecting inner beans as ApplicationListeners.
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		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中没有名为systemProperties,systemEnvironment,environment的bean则注册
		 * bean key为‘systemEnvironment’,‘environment’ 和‘systemProperties’
		 * 这两个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.容器创建初期创建了两个对象 xxreader和scanner 并在beanMap中加入了6个对象,为后续操作提供支持。需要关注ConfigurationClassPostProcessor比较重要和特殊。
2.后置处理器是spring的强大之处,可以插手bean的创建。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值