Spring-IOC(一)

Spring家族是我们工作中天天打交道的,这个框架帮我们省去了很多繁琐的工作,但也带来了一定的麻烦,那就是有时框架封装的太好,出现了错误不了解源码的情况下不知道该如何下手。

image

上图就是spring框架的结构,我们平时说的IOC就是在core container中。

bean和对象的区别

spring中管理的bean和我们普通new出来的对象有什么区别呢?
比如我们创建一个Person对象,对象的属性有age、name、gender等属性,这是我们平时创建对象的属性;当我们把这个对象交由spring管理变成一个bean对象时,那么会是什么样的呢?其实由spring管理的bean也是一个对象,只不过这个bean对象比普通对象多了一些特有的属性,比如bean的作用域、加载方式等等。这些属性是spring加载bean的时候注入的

注解启动spring

先来一段代码,看下完全脱离xml配置文件是如何将一个spring项目启动起来,如果将一个对象加载到spring容器中并应用的

public class Main {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
		AspectService aspectService = context.getBean("aspectService", AspectService.class);
		aspectService.test();
	}
}

@Configuration
@ComponentScan("com.xxx.spring.aspect")
@PropertySource("classpath:application.properties")
public class AppConfig {

}

@org.springframework.stereotype.Service
public class AspectService implements Service{

	@Override
	public void test(){
		System.err.println("AOP test");
	}
}

上面几段程序就可以将spring启动起来并打印出相应的结果。那么在上面的程序中每个注解有什么含义,在哪一步进行解析的呢?这些都会在后续的源码中体现出来。

AnnotationConfigApplicationContext

这个类是启动的关键,在创建该对象时传入了AppConfig.class,那么在该对象的构造方法中做了哪些操作呢?看下对应的构造方法:

	public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		this();
		register(componentClasses);
		refresh();
	}

这个构造方法很简单,就三步:

  1. 调用无参构造
  2. 调用register方法将传入的class进行注册,这里传入的是AppConfig
  3. 调用refresh方法

调用无参构造

首先调用的是该类的无参构造,在看无参构造代码之前,先看下这个类的UML图
image

看到这个类的UML图还是蛮复杂的,那么这个类的无参构造主要是看它的父类做了什么

// GenericApplicationContext类的构造方法
	public GenericApplicationContext() {
		this.beanFactory = new DefaultListableBeanFactory();
	}
// AnnotationConfigApplicationContext类的构造方法
	public AnnotationConfigApplicationContext() {
		this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

可以看到在调用AnnotationConfigApplicationContext类之前需要先调用父类GenericApplicationContext类的构造方法。在GenericApplicationContext的无参构造中,只是对属性beanFactory进行了初始化,初始化为DefaultListableBeanFactory,这个类非常重要,后续bean的一系列操作都会用到这个类。接着执行AnnotationConfigApplicationContext类的无参构造,分别对reader和scanner进行初始化。

在说AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner之前先看下DefaultListableBeanFactory类的UML图
image

AnnotatedBeanDefinitionReader

这个类主要确定环境变量以及spring自己添加的一个processor到beanDefinitionMap中

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
	this(registry, getOrCreateEnvironment(registry));
}

private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
	Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
	if (registry instanceof EnvironmentCapable) {
		return ((EnvironmentCapable) registry).getEnvironment();
	}
	return new StandardEnvironment();
}

获取或创建Environment
首先调用getOrCreateEnvironment方法获取环境变量,根据AnnotationConfigApplicationContext类的UML图可以看出该类既是BeanDefinitionRegistry的子类,又是EnvironmentCapable子类,所以在getOrCreateEnvironment方法中会进入if条件的判断

public ConfigurableEnvironment getEnvironment() {
	if (this.environment == null) {
		this.environment = createEnvironment();
	}
	return this.environment;
}

最终调用的是StandardEnvironment的构造方法,该类的无参构造方法什么也没做,但该类有两个成员变量:

/** System environment property source name: {@value}. */
public static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME = "systemEnvironment";

/** JVM system properties property source name: {@value}. */
public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties";

一个是系统环境一个是系统参数。这样就创建了一个StandardEnvironment类型的环境变量
注册processor
环境变量创建好之后就开始注册一些processor,这些processor在后续spring bean相关操作中都会用到

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);
}

可以看到上面的代码主要是registerAnnotationConfigProcessors方法:

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {

	DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
	if (beanFactory != null) {
		if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
			beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
		}
		if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
			beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
		}
	}

	Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

	if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		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 (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));
	}

	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,这里获取的就是DefaultListableBeanFactory
  • 创建BeanDefinitionHolder集合(这是一个set集合,是为了去重),存放注册好的processor,这里注册好是说processor放入了DefaultListableBeanFactory中的beanDefinitionMap中。
  • 判断beanDefinitionMap中是否含有"org.springframework.context.annotation.internalConfigurationAnnotationProcessor",如果不存在,将ConfigurationClassPostProcessor包装成RootBeanDefinition对象,然后将RootBeanDefinition注册到beanDefinitionMap中

ConfigurationClassPostProcessor类是BeanFactoryPostProcessor的实现类,主要是解析spring中符合注解条件的类(@Configuration注解的、@Component、@ComponentScan、@Import、@ImportResource或者@Bean注解的),并将该类加入到beanDefinitionMap中

  • 判断beanDefinitionMap中是否含有"org.springframework.context.annotation.internalAutowiredAnnotationProcessor",如果不存在,将AutowiredAnnotationBeanPostProcessor包装成RootBeanDefinition对象,然后将RootBeanDefinition注册到beanDefinitionMap中

AutowiredAnnotationBeanPostProcessor是BeanPostProcessor的实现类,该类能够自动装配被注解Autowired、Value注解的属性、setter方法以及配置方法,这些类成员能够被自动的检测到并注入

  • 判断beanDefinitionMap中是否含有"org.springframework.context.annotation.internalCommonAnnotationProcessor",如果不存在,将CommonAnnotationBeanPostProcessor包装成RootBeanDefinition对象,然后将RootBeanDefinition注册到beanDefinitionMap中

CommonAnnotationBeanPostProcessor是BeanPostProcessor的实现类,主要处理@Resource、@PostConstruct和@PreDestroy注解的实现

  • 判断beanDefinitionMap中是否含有"org.springframework.context.annotation.internalPersistenceAnnotationProcessor",如果不存在,使用反射机制获取PersistenceAnnotationBeanPostProcessor类,并将该类包装成RootBeanDefinition对象,然后将RootBeanDefinition注册到beanDefinitionMap中

PersistenceAnnotationBeanPostProcessor是用于JPA的支持

  • 判断beanDefinitionMap中是否含有"org.springframework.context.event.internalEventListenerProcessor",如果不存在,将EventListenerMethodProcessor包装成RootBeanDefinition对象,然后将RootBeanDefinition注册到beanDefinitionMap中

EventListenerMethodProcessor处理监听方法的注解解析器EventListenerMethodProcessor -- > @EventListener

  • 判断beanDefinitionMap中是否含有"org.springframework.context.event.internalEventListenerFactory",如果不存在,将DefaultEventListenerFactory包装成RootBeanDefinition对象,然后将 RootBeanDefinition注册到beanDefinitionMap中

DefaultEventListenerFactory注册事件监听器工厂,注册默认 @EventListener 方法解析工厂

ClassPathBeanDefinitionScanner

这个主要是设置resource和环境环境,没什么好说的,都是一些赋值操作

register

无参构造执行完之后就接着执行register方法,将传递进来的class注册到beanDefinitionMap中,最终调用方法在:org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean

<T> void doRegisterBean(Class<T> beanClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {

	// 将beanClass中对应的注解解析出来放入StandardAnnotationMetadata类中的annotations属性中。
	// StandardAnnotationMetadata在AnnotatedGenericBeanDefinition类中的属性名是metadata
	AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
	/*
	 根据获取到注解判断是否需要跳过该注册
	*/
	if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
		return;
	}
	// 该方法主要是为了支持Java8创建对象的方式
	abd.setInstanceSupplier(instanceSupplier);
	// 解析是否有@Scope注解,如果有判断作用域是否是singleton,如果没有,默认就是singleton
	ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
	abd.setScope(scopeMetadata.getScopeName());
	// 根据传递的class获取对应的beanName
	String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
	// 判断abd中是有含有@Lazy、@Primary、@DependsOn、@Role、@Description这五个注解,如果有的话,获取这五个注解中对应的value
	// 放入abd属性中
	AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
	// 特定限定符处理
	if (qualifiers != null) {
		for (Class<? extends Annotation> qualifier : qualifiers) {
			if (Primary.class == qualifier) {
				abd.setPrimary(true);
			}
			else if (Lazy.class == qualifier) {
				abd.setLazyInit(true);
			}
			else {
				abd.addQualifier(new AutowireCandidateQualifier(qualifier));
			}
		}
	}
	// 如果传递进来的definitionCustomizers不为空,则对自定义的BeanDefinition处理
	for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
		customizer.customize(abd);
	}
	// 根据abd和beanName构造BeanDefinitionHolder
	BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
	definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
	// 将传递进来的class放入beanDefinitionMap中
	BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
posted @ 2021-07-26 17:25  扭不动的奥利奥  阅读(56)  评论(0)    收藏  举报