spring源码

1.spring架构

 由架构可以看出,spring核心是BeanFactory,可以比做现实生活中工厂。

我们看看一个工厂的大致工作流程:

  1. 工厂加工一个产品需要有图纸,图纸存放于档案库。
  2. 有了图纸,需要车间流水线,这个流水线能加工产品,就需要人、加工机器、水电气等等加工环境。
  3. 环境准备工作好了,就可以按照图纸加工产品了。

再来看看spring生产Bean的大致过程:

  1. 现实中的零件图纸,在spring中称作BeanDefinition(Bean定义信息),spring要得到Bean定义信息,需要将资源Resource(xml、注解)解析出来得到Bean定义信息,并保存起来。
  2. 工厂需要加工环境,spring也是一样,需要一些环境,比如加载java的Properties。
  3. 有了BeanDefinition,就可以创建Bean,在创建Bean的过程中,spring定义后置处理器在一些步骤进行干预,最后完成Bean创建。这里也被称作Bean生命周期过程。

2.Spring容器刷新

测试方法

/**
 * 注解版Spring的用法
 */
public class AnnotationMainTest {

	public static void main(String[] args) {
//		new ClassPathXmlApplicationContext()

		ApplicationContext applicationContext =
				new AnnotationConfigApplicationContext(MainConfig.class);
    }
}

进入构造方法

	/**
	 * Create a new AnnotationConfigApplicationContext, deriving bean definitions
	 * from the given component classes and automatically refreshing the context.
	 * @param componentClasses one or more component classes — for example,
	 * {@link Configuration @Configuration} classes
	 */
	public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		this();
		register(componentClasses);
		refresh(); //容器完整刷新(创建出所有组件,组织好所有功能)
	}

进入refresh()方法,所有关键逻辑都在这里面

	@Override  //容器刷新的十二大步。模板模式
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

			//1.准备上下文环境 Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			// 2.工厂创建:BeanFactory第一次开始创建的时候,有xml解析逻辑。
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			//3.给容器中注册了环境信息作为单实例Bean方便后续自动装配;放了一些后置处理器处理(监听、xxAware功能) Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				//4.留给子类的模板方法,允许子类继续对工厂执行一些处理; Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
				//5.【大核心】工厂增强:执行所有的BeanFactory后置增强器;利用BeanFactory后置增强器对工厂进行修改或者增强,配置类会在这里进行解析。 Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				//6.【核心】注册所有的Bean的后置处理器 Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);
				beanPostProcess.end();

				//7.初始化国际化功能 Initialize message source for this context.
				initMessageSource();

				//8.初始化事件多播功能(事件派发) Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// 9.Initialize other special beans in specific context subclasses.
				onRefresh();

				//10.注册监听器,从容器中获取所有的ApplicationListener; Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				//11.【大核心】bean创建;完成 BeanFactory 初始化。(工厂里面所有的组件都好了)
				finishBeanFactoryInitialization(beanFactory);

				//12.发布事件 Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
				contextRefresh.end();
			}
		}
	}

源码调试方法:在关键的方法处打断点,然后查看堆栈调用

3.Aware接口:帮我们装配Spring底层的一些组件

1、Bean的功能增强全部都是有 BeanPostProcessor+InitializingBean  (合起来完成的)
2、骚操作就是 BeanPostProcessor+InitializingBean

Aware接口的流程图

看一下Aware的子接口:

 Aware接口作用是什么?

aware翻译过来是感知。

什么是感知,根据字面意思还是不怎么理解,但是我们看看实现了Aware接口,需要实现的方法。大致可以看出,Aware的作用。

比如setApplicationContext(ApplicationContext applicationContext)。

该方法将容器传过来了,这个时候我们拿到了容器的引用,我们就可以对容器进行一些操作。

由此大致可以理解Aware接口的作用:通过实现这些接口,我们可以拿到容器的某种组件,进而根据组件的暴露的api,来实现我们自己的一些逻辑。

 准备Person,该类标注了@Component,将Person成为一个组件,同时实现了ApplicationContextAware,MessageSourceAware接口。Person继承树如下

/**
 * Aware接口;帮我们装配Spring底层的一些组件
 * 1、Bean的功能增强全部都是有 BeanPostProcessor+InitializingBean  (合起来完成的)
 * 2、骚操作就是 BeanPostProcessor+InitializingBean
 *
 * 你猜Autowired是怎么完成的
 * Person为什么能把ApplicationContext、MessageSource当为自己的参数传进来。
 * 	  - 通过实现接口的方式自动注入了 ApplicationContext、MessageSource。是由BeanPostProcessor(Bean的后置处理器完成的)
 *
 */
@Component
public class Person implements ApplicationContextAware, MessageSourceAware {

//	@Autowired
	ApplicationContext context;  //可以要到ioc容器
	MessageSource messageSource;

	public Person(){
		System.out.println("person创建....");
	}
//
//	public ApplicationContext getContext() {
//		return context;
//	}

	private String name;

//	@Autowired  依赖的组件是多实例就不能Autowired
	private Cat cat;


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

	public String getName() {
		return name;
	}

	@Autowired  //去发现一下.....
	public void setCat(Cat cat) {
		this.cat = cat;
	}

	//
//	@Lookup  //去容器中找。@Bean的这种方式注册的Person @Lookup不生效
	public Cat getCat() {
		return cat;
	}

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

	public ApplicationContext getContext() {
		return context;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		//利用回调机制,把ioc容器传入
		this.context = applicationContext;
	}

	@Override
	public void setMessageSource(MessageSource messageSource) {
		this.messageSource = messageSource;
	}
}

setApplicationContext(ApplicationContext applicationContext)在什么时候被调用?

1.初始调用构造

		ApplicationContext applicationContext =
				new AnnotationConfigApplicationContext(MainConfig.class);

2.调用父类

3.调用finishBeanFactoryInitialization()

 4. this->DefaultListableBeanFactory,调用preInstantiateSingletons()

5. this->DefaultListableBeanFactory,父类方法调用getBean()

 6.this->DefaultListableBeanFactory,父类方法调用doGetBean()

  7.this->DefaultListableBeanFactory,父类方法调用getSingleton()

8.this->DefaultListableBeanFactory,调用到父类AbstractAutowireCapableBeanFactory的creatBean()

 

9.this->DefaultListableBeanFactory,调用到AbstractAutowireCapableBeanFactory的doCreatBean()

10.this->DefaultListableBeanFactory,调用到AbstractAutowireCapableBeanFactory的initializeBean()

 

 11.this->DefaultListableBeanFactory,调用到AbstractAutowireCapableBeanFactory的applyBeanPostProcessorsBeforeInitialization()

  11.this->ApplicationContextAwareProcessor,调用postProcessBeforeInitialization()

  12.this->ApplicationContextAwareProcessor,调用invokeAwareInterfaces()

 13.person利用反射调用到实现方法

总结:

  1. person创建Bean时机,在finishBeanFactoryInitialization()
  2. setApplicationContext,也发生在finishBeanFactoryInitialization()
  3. 处理ApplicationContextAware接口,是因为Spring为其创建了对应的ApplicationContextAwareProcessor后置处理器,该类实现了BeanPostProcessor接口。在Bean增强环节,调用了对应方法。
 * <p>Application contexts will automatically register this with their
 * underlying bean factory. Applications do not use this directly.
 * BeanPostProcessor:Bean的后置处理器
 * @author Juergen Hoeller
 * @author Costin Leau
 * @author Chris Beams
 * @since 10.10.2003
 * @see org.springframework.context.EnvironmentAware
 * @see org.springframework.context.EmbeddedValueResolverAware
 * @see org.springframework.context.ResourceLoaderAware
 * @see org.springframework.context.ApplicationEventPublisherAware
 * @see org.springframework.context.MessageSourceAware
 * @see org.springframework.context.ApplicationContextAware
 * @see org.springframework.context.support.AbstractApplicationContext#refresh()
 */
class ApplicationContextAwareProcessor implements BeanPostProcessor {}

ApplicationContextAwareProcessor什么时候被Spring创建的?

将ApplicationContextAwareProcessor的构造方法打上断点

 在prepareBeanFactory(),Spring直接new出来方法容器里。

3.BeanFactoryPostProcessor

这个接口增强了什么?

spring底层类ConfigurationClassPostProcessor给我们做了示例

/**
 * {@link BeanFactoryPostProcessor} used for bootstrapping processing of
 * {@link Configuration @Configuration} classes.
 *
 * <p>Registered by default when using {@code <context:annotation-config/>} or
 * {@code <context:component-scan/>}. Otherwise, may be declared manually as
 * with any other {@link BeanFactoryPostProcessor}.
 *
 * <p>This post processor is priority-ordered as it is important that any
 * {@link Bean @Bean} methods declared in {@code @Configuration} classes have
 * their corresponding bean definitions registered before any other
 * {@code BeanFactoryPostProcessor} executes.
 * 主要用来解析主配置类的
 * @author Chris Beams
 * @author Juergen Hoeller
 * @author Phillip Webb
 * @author Sam Brannen
 * @since 3.0
 */
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
		PriorityOrdered, ResourceLoaderAware, ApplicationStartupAware, BeanClassLoaderAware, EnvironmentAware {}

ConfigurationClassPostProcessor 会解析我们的配置类,注册Bean定义信息。

4.探索@Autowired执行时机

断点如下

还是发生在finishBeanFactoryInitialization(beanFactory)-->doCreateBean()-->populateBean()属性设置

 

 后置处理器是AutowiredAnnotationBeanPostProcessor,最终还是属于BeanPostProcessor

5.探索BeanPostProcessor 干预生命周期过程