SpringApplication源码阅读
0. 一些基本概念
BeanDefinition
容器中的每一个bean都会有一个对应的BeanDefinition
实例,该实例负责保存bean对象的 所有 必要信息,包括bean对象的class类型、是否是抽象类、构造方法和参数、其它属性等等
1. SpringBootApplication注解
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
@...
public @interface SpringBootApplication {
@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};
@AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
}
@SpringBootConfiguration
@Configuration
@...
public @interface SpringBootConfiguration {
}
这个注解与@Configuration作用是一样的;
@EnableAutoConfiguration
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
@...
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
这个注解用于开启自动配置;这个注解又包含两个注解:
- @AutoConfigurationPackage:开启包扫描
- @Import(AutoConfigurationImportSelector.class):通过@Import将AutoConfigurationImportSelector.class加入IOC容器中;
总结
总的来说,@SpringBootApplication这个注解在主程序启动前,主要做的是以下几件事:
- @ComponentScan:开启组件扫描
- @Configuration:申明当前类是一个配置类
- @AutoConfigurationPackage:开启包扫描
- @Import(AutoConfigurationImportSelector.class):引入了一个关键类,这个类的作用是啥后面会说
2. SpringApplication初始化
@SpringBootApplication
public class MymbgApplication {
public static void main(String[] args) {
SpringApplication.run(MymbgApplication.class, args);
}
}
启动的入口是SpringApplication.run()方法,这是一个静态方法,第一个参数接收一个Spring容器配置类,第二个参数是命令行参数,点进去看,可以看到它调用了一个内部方法;
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return run(new Class<?>[] { primarySource }, args);
}
在内部的run方法中,是先创建了一个SpringApplication的对象,再通过这个对象启动;
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return new SpringApplication(primarySources).run(args);
}
然后点到最终调用的构造器
public SpringApplication(Class<?>... primarySources) {
this(null, primarySources);
}
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));// 1. 初始化了Spring容器的配置类
this.webApplicationType = WebApplicationType.deduceFromClasspath();//2. 判断并初始化了应用程序的类型
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));//3. 初始化了ApplicationContextInitializer的列表
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));//4. 初始化了ApplicationListener的列表
this.mainApplicationClass = deduceMainApplicationClass();// 5. 推断了主类的名称
}
这个构造器进行spring容器的初始化,主要做了几件事:
- 初始化了Spring容器的配置类
- 判断并初始化了应用程序的类型
- 初始化了ApplicationContextInitializer的列表
- 初始化了ApplicationListener的列表
- 推断了主类的名称
初始化配置类
初始化时用的配置类就是主程序中run的第一个参数,就是我们主程序的类;
初始化应用程序的类型
static WebApplicationType deduceFromClasspath() {
if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
return WebApplicationType.REACTIVE;
}
for (String className : SERVLET_INDICATOR_CLASSES) {
if (!ClassUtils.isPresent(className, null)) {
return WebApplicationType.NONE;
}
}
return WebApplicationType.SERVLET;
}
有三种类型:1. reactive 2. none 3. servlet;
判断的逻辑就是检查classpath下是否存在对应的类;
初始化ApplicationContextInitializer
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = getClassLoader();
// Use names and ensure unique to protect against duplicates
// 获取与ApplicationContextInitializer相关的类名
Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
首先调用的是SpringFactoriesLoader类的loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader)方法;用于获取与ApplicationContextInitializer相关的类名;
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap<String, String> result = cache.get(classLoader);
if (result != null) {
return result;
}
try {
// 到指定的目录下获取配置信息,目录的地址是META-INF/spring.factories
Enumeration<URL> urls = (classLoader != null ?
classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
result = new LinkedMultiValueMap<>();
while (urls.hasMoreElements()) {// 遍历的对配置信息进行处理,处理的逻辑就是将配置的键值对储存到一个MultiValueMap中,并且将这个map存到缓存中
URL url = urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
for (Map.Entry<?, ?> entry : properties.entrySet()) {
String factoryClassName = ((String) entry.getKey()).trim();
for (String factoryName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
result.add(factoryClassName, factoryName.trim());
}
}
}
cache.put(classLoader, result);
return result;
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load factories from location [" +
FACTORIES_RESOURCE_LOCATION + "]", ex);
}
}
首先会到指定的目录下获取配置信息,目录的地址是META-INF/spring.factories;总共有6个initializer,然后遍历的对配置信息进行处理,处理的逻辑就是将配置的键值对储存到一个MultiValueMap中,并且将这个map存到缓存中;
# spring-boot-autoconfigure jar中的META-INF/spring.factories
# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
# spring-boot jar中的META-INF/spring.factories
# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
获取了initializer的name列表后再对所有initializer初始化,初始化的过程就是通过反射创建实例,然后存到一个instances列表中;
private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes,
ClassLoader classLoader, Object[] args, Set<String> names) {
List<T> instances = new ArrayList<>(names.size());
for (String name : names) {
try {
Class<?> instanceClass = ClassUtils.forName(name, classLoader);
Assert.isAssignable(type, instanceClass);
Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
T instance = (T) BeanUtils.instantiateClass(constructor, args);
instances.add(instance);
}
catch (Throwable ex) {
throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex);
}
}
return instances;
}
初始化ApplicationListener
初始化的过程与ApplicationContextInitializer的过程是一致的,不详细展开;
推断主程序的名字
private Class<?> deduceMainApplicationClass() {
try {
StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
for (StackTraceElement stackTraceElement : stackTrace) {
if ("main".equals(stackTraceElement.getMethodName())) {
return Class.forName(stackTraceElement.getClassName());
}
}
}
catch (ClassNotFoundException ex) {
// Swallow and continue
}
return null;
}
这个过程很巧妙,是到jvm的异常堆栈中找到方法是main的累,将其作为主类;
3. SpringApplication启动
在执行完成所有的初始化后,就通过run方法开始启动容器了;
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
// 1. 获取runnerlitseners
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 2. 创建并配置Environment 包括profile和PropertySource
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
configureIgnoreBeanInfo(environment);
// 3. 打印banner,控制台的横幅就是这个
Banner printedBanner = printBanner(environment);
// 4. 创建并初始化ApplicationContext
context = createApplicationContext();
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
refreshContext(context);
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}
启动过程主要做几件事:
- 获取runnerlisteners
- 创建并配置Environment,包括profile和PropertySource
- 打印banner,控制台的横幅就是这个
- 创建并初始化ApplicationContext
获取runnerListeners
SpringApplicationRunListeners listeners = getRunListeners(args);
private SpringApplicationRunListeners getRunListeners(String[] args) {
Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
return new SpringApplicationRunListeners(logger,
getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
}
获取listeners的过程与springApplication初始化时一致,仍然是通过SpringFactoriesLoader的机制加载所有的SpringApplicationRunListener;
SpringApplicationRunListener的作用就是监听SpringApplication.run()方法的各个执行阶段;
SpringApplicationRunListeners就是SpringApplicationRunListener的封装集合,可以使用它的api来操作所有的listener;
listeners.starting();
获取listener后,就通过listeners.starting()通知所有listener SpringBoot应用要启动了;
创建并配置Environment
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
configureIgnoreBeanInfo(environment);
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments) {
// Create and configure the environment
ConfigurableEnvironment environment = getOrCreateEnvironment();//1. 根据应用类型获取environment
configureEnvironment(environment, applicationArguments.getSourceArgs());// 2. 使用命令行参数配置environment
listeners.environmentPrepared(environment);// 3. 通知监听器 environment准备好了
bindToSpringApplication(environment);// 4. 将environment与SpringApplication应用绑定
if (!this.isCustomEnvironment) {
environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
deduceEnvironmentClass());
}
ConfigurationPropertySources.attach(environment);
return environment;
}
根据应用类型获取environment
private ConfigurableEnvironment getOrCreateEnvironment() {
if (this.environment != null) {
return this.environment;
}
switch (this.webApplicationType) {
case SERVLET:
return new StandardServletEnvironment();
case REACTIVE:
return new StandardReactiveWebEnvironment();
default:
return new StandardEnvironment();
}
}
StandardServletEnvironment类继承了standardEnvironment类,standardEnvironment类继承了AbstractEnvironment,最终执行的是AbstractEnvironment的构造器
public AbstractEnvironment() {
customizePropertySources(this.propertySources);
}
在构造器中执行了customizePropertySources方法,这个方法被StandardServletEnvironment和standardEnvironment重写了
protected void customizePropertySources(MutablePropertySources propertySources) {
propertySources.addLast(new StubPropertySource(SERVLET_CONFIG_PROPERTY_SOURCE_NAME));
propertySources.addLast(new StubPropertySource(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME));
if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {
propertySources.addLast(new JndiPropertySource(JNDI_PROPERTY_SOURCE_NAME));
}
super.customizePropertySources(propertySources);
}
protected void customizePropertySources(MutablePropertySources propertySources) {
propertySources.addLast(
new PropertiesPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties()));
propertySources.addLast(
new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment()));
}
然后看到最关键的两个方法getSystemProperties()和getSystemEnvironment();这两个方法最终调用的是System.getProperties()和System.getenv(),到这里spring容器就获取到了环境和属性信息
配置environment,同时配置profile和propertySources
protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
if (this.addConversionService) {
ConversionService conversionService = ApplicationConversionService.getSharedInstance();
environment.setConversionService((ConfigurableConversionService) conversionService);
}
configurePropertySources(environment, args);
configureProfiles(environment, args);
}
配置PropertySources
protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) {
MutablePropertySources sources = environment.getPropertySources();
if (this.defaultProperties != null && !this.defaultProperties.isEmpty()) {
sources.addLast(new MapPropertySource("defaultProperties", this.defaultProperties));
}
if (this.addCommandLineProperties && args.length > 0) {
String name = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME;
if (sources.contains(name)) {
PropertySource<?> source = sources.get(name);
CompositePropertySource composite = new CompositePropertySource(name);
composite.addPropertySource(
new SimpleCommandLinePropertySource("springApplicationCommandLineArgs", args));
composite.addPropertySource(source);
sources.replace(name, composite);
}
else {
sources.addFirst(new SimpleCommandLinePropertySource(args));
}
}
}
配置profile
protected void configureProfiles(ConfigurableEnvironment environment, String[] args) {
environment.getActiveProfiles(); // ensure they are initialized
// But these ones should go first (last wins in a property key clash)
Set<String> profiles = new LinkedHashSet<>(this.additionalProfiles);
profiles.addAll(Arrays.asList(environment.getActiveProfiles()));
environment.setActiveProfiles(StringUtils.toStringArray(profiles));
}
getActiveProfiles最终会调用doGetActiveProfiles方法,这个方法会去查找属性spring.profiles.active来获得活动的profile
protected Set<String> doGetActiveProfiles() {
synchronized (this.activeProfiles) {
if (this.activeProfiles.isEmpty()) {
String profiles = getProperty(ACTIVE_PROFILES_PROPERTY_NAME);
if (StringUtils.hasText(profiles)) {
setActiveProfiles(StringUtils.commaDelimitedListToStringArray(
StringUtils.trimAllWhitespace(profiles)));
}
}
return this.activeProfiles;
}
}
配置好之后,就通过listeners.environmentPrepared来通知监听器environment准备好了,同时此时监听器会触发事件,
private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {
List<EnvironmentPostProcessor> postProcessors = loadPostProcessors();//
postProcessors.add(this);
AnnotationAwareOrderComparator.sort(postProcessors);
for (EnvironmentPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessEnvironment(event.getEnvironment(), event.getSpringApplication());
}
}
loadPostProcessors()方法调用SpringFactoriesLoader.loadFactories()方法,到META-INF/spring.factories下查找EnvironmentPostProcessor.class的键值对
List<EnvironmentPostProcessor> loadPostProcessors() {
return SpringFactoriesLoader.loadFactories(EnvironmentPostProcessor.class, getClass().getClassLoader());
}
然后最终会执行ConfigFileApplicationListener的addPropertySources方法,这个方法就是读取配置的方法了
protected void addPropertySources(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {
RandomValuePropertySource.addToEnvironment(environment);
new Loader(environment, resourceLoader).load();
}
他先是new的一个Loader实例,可以看到这个构造器内通过SpringFactoriesLoader.loadFactories查找和获取了PropertySourceLoader.class的实例,分别是
PropertiesPropertySourceLoad和YamlPropertySourceLoader,这就能解释为什么spring boot支持两种配置文件
Loader(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {
this.environment = environment;
this.placeholdersResolver = new PropertySourcesPlaceholdersResolver(this.environment);
this.resourceLoader = (resourceLoader != null) ? resourceLoader : new DefaultResourceLoader();
this.propertySourceLoaders = SpringFactoriesLoader.loadFactories(PropertySourceLoader.class,
getClass().getClassLoader());
}
然后调用Loader.load,然后load里调用load,用于创建当前的profile的document实例,来获取spring.profile.active指向的profile
public void load() {
this.profiles = new LinkedList<>();
this.processedProfiles = new LinkedList<>();
this.activatedProfiles = false;
this.loaded = new LinkedHashMap<>();
initializeProfiles();
while (!this.profiles.isEmpty()) {
Profile profile = this.profiles.poll();
if (profile != null && !profile.isDefaultProfile()) {
addProfileToEnvironment(profile.getName());
}
load(profile, this::getPositiveProfileFilter, addToLoaded(MutablePropertySources::addLast, false));
this.processedProfiles.add(profile);
}
resetEnvironmentProfiles(this.processedProfiles);
load(null, this::getNegativeProfileFilter, addToLoaded(MutablePropertySources::addFirst, true));
addLoadedPropertySources();
}
load先会用asDocuments方法创建一个profile document对象,ACTIVE_PROFILES_PROPERTY的值就是spring.profile.active
private List<Document> asDocuments(List<PropertySource<?>> loaded) {
if (loaded == null) {
return Collections.emptyList();
}
return loaded.stream().map((propertySource) -> {
Binder binder = new Binder(ConfigurationPropertySources.from(propertySource),
this.placeholdersResolver);
return new Document(propertySource, binder.bind("spring.profiles", STRING_ARRAY).orElse(null),
getProfiles(binder, ACTIVE_PROFILES_PROPERTY), getProfiles(binder, INCLUDE_PROFILES_PROPERTY));//创建profile document对象
}).collect(Collectors.toList());
}
最后调用addLoadedPropertySources将配置添加到environment中
private void addLoadedPropertySources() {
MutablePropertySources destination = this.environment.getPropertySources();
List<MutablePropertySources> loaded = new ArrayList<>(this.loaded.values());
Collections.reverse(loaded);
String lastAdded = null;
Set<String> added = new HashSet<>();
for (MutablePropertySources sources : loaded) {
for (PropertySource<?> source : sources) {
if (added.add(source.getName())) {
addLoadedPropertySource(destination, lastAdded, source);
lastAdded = source.getName();
}
}
}
}
最后配好的environment如下图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-15CEva53-1641627287075)(Spring%20Boot%E5%90%AF%E5%8A%A8%E5%8E%9F%E7%90%86-SpringApplication.assets/image-20211222173028188.png)]
创建并初始化ApplicationContext
首先是通过应用类型获取不同类型的context
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
switch (this.webApplicationType) {
case SERVLET:
contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
break;
case REACTIVE:
contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
break;
default:
contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
}
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Unable create a default ApplicationContext, " + "please specify an ApplicationContextClass",
ex);
}
}
return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}
然后通过prepareContext方法对context进行初始化,包括启动类bean的注入
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
context.setEnvironment(environment);//配置environment
postProcessApplicationContext(context);//根据条件决定是否添加ShutdownHook,是否使用自定义的BeanNameGenerator,是否使用自定义的ResourceLoader
applyInitializers(context);//进行context的初始化
listeners.contextPrepared(context);//通知监听器context准备好了
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
// Add boot specific singleton beans
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
if (beanFactory instanceof DefaultListableBeanFactory) {
((DefaultListableBeanFactory) beanFactory)
.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
// Load the sources
Set<Object> sources = getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
load(context, sources.toArray(new Object[0]));//加载bean
listeners.contextLoaded(context);
}
根据条件决定是否添加ShutdownHook,是否使用自定义的BeanNameGenerator,是否使用自定义的ResourceLoader
protected void postProcessApplicationContext(ConfigurableApplicationContext context) {
if (this.beanNameGenerator != null) {
context.getBeanFactory().registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR,
this.beanNameGenerator);
}
if (this.resourceLoader != null) {
if (context instanceof GenericApplicationContext) {
((GenericApplicationContext) context).setResourceLoader(this.resourceLoader);
}
if (context instanceof DefaultResourceLoader) {
((DefaultResourceLoader) context).setClassLoader(this.resourceLoader.getClassLoader());
}
}
if (this.addConversionService) {
context.getBeanFactory().setConversionService(ApplicationConversionService.getSharedInstance());
}
}
然后调用applyInitializers方法,在这个方法中,调用所有ApplicationContextInitializer的initialize方法,完成ApplicationContext的初始化;
protected void applyInitializers(ConfigurableApplicationContext context) {
for (ApplicationContextInitializer initializer : getInitializers()) {
Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),
ApplicationContextInitializer.class);
Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
initializer.initialize(context);
}
}
调用load加载和自动装配bean,主要装配的是启动类的bean,以为后面的自动装配提供配置信息
Set<Object> sources = getAllSources();//获取需要加载的bean的信息
Assert.notEmpty(sources, "Sources must not be empty");
load(context, sources.toArray(new Object[0]));//加载bean
load方法会遍历进行装配,最终调用的是下面这个load方法;
private int load(Class<?> source) {
if (isGroovyPresent() && GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {
// Any GroovyLoaders added in beans{} DSL can contribute beans here
GroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class);
load(loader);
}
if (isComponent(source)) {
this.annotatedReader.register(source);
return 1;
}
return 0;
}
先通过instantiateClass方法,创建bean的实例,
public static <T> T instantiateClass(Class<T> clazz) throws BeanInstantiationException {
Assert.notNull(clazz, "Class must not be null");
if (clazz.isInterface()) {//如果是接口类型的类,则抛出异常
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
return instantiateClass(clazz.getDeclaredConstructor());
}
catch (NoSuchMethodException ex) {
Constructor<T> ctor = findPrimaryConstructor(clazz);
if (ctor != null) {
return instantiateClass(ctor);
}
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
catch (LinkageError err) {
throw new BeanInstantiationException(clazz, "Unresolvable class definition", err);
}
}
利用反射方法使用构造器
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}
创建好bean的实体后,判断这个类是否有@Component注解,有则进行注册
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
SimpleBeanDefinitionRegistry实现的registerBeanDefinition
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "'beanName' must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
this.beanDefinitionMap.put(beanName, beanDefinition);
}
自动装配
自动装配的入口是AbstractApplicationContext.refresh()
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备,记录容器的启动时间startupDate, 标记容器为激活,初始化上下文环境如文件路径信息,验证必填属性是否填写
prepareRefresh();
// 这步比较重要(解析),告诉子类去刷新bean工厂,这步完成后配置文件就解析成一个个bean定义,注册到BeanFactory(但是未被初始化,仅将信息写到了beanDefination的map中)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 设置beanFactory类加载器,添加多个beanPostProcesser
prepareBeanFactory(beanFactory);
try {
// 允许子类上下文中对beanFactory做后期处理
postProcessBeanFactory(beanFactory);
// 自动装配的核心方法 调用BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor进行bd的创建注册修改
invokeBeanFactoryPostProcessors(beanFactory);
// 注册 BeanPostProcessor 的实现类,bean后置处理器,bean创建对象初始化前后进行拦截工作的
// 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
// 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
registerBeanPostProcessors(beanFactory);
// 初始化ApplicationContext的MessageSource
initMessageSource();
// 初始化ApplicationContext事件广播器
initApplicationEventMulticaster();
// 初始化子类特殊bean(钩子方法)
onRefresh();
// 注册事件监听器
registerListeners();
// 初始化所有singleton bean
finishBeanFactoryInitialization(beanFactory);
// 广播事件,ApplicationContext初始化完成
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();
}
}
}
自动装配的核心方法是PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors
涉及的核心的类是BeanDefinitionRegistryPostProcessor.class,该类负责处理了包扫描的功能
这个方法的第二个参数是由开发人员自定义传入;
阅读这个方法需要先认识几个类的概念:
- beanfactory:是一个最基本的工厂类,它是IOC容器创建的工厂,通过不同的工厂实现,从不同的配置文件中获取配置生成对应的对象注入IOC容器
- BeanDefinition:BeanDefinition是bean在spring中的描述,里面存放Bean元数据,比如Bean类名、scope、属性、构造函数参数列表、依赖的bean、是否是单例类、是否是懒加载等一些列信息;beanFactory就是根据BeanDefinition来创建bean;
- BeanDefinitionRegistry:BeanDefinition的注册中心,保存了所有beanDefinition
- bean:是对象实例
- BeanFactoryPostProcessor:beanFactory后置处理器,在beanFactory标准初始化之后调用,此时所有的beanDefinition已经保存加载到beanFactory中,但bean的实例还未创建,此时可以对bean的属性进行修改拓展
- BeanDefinitionRegistryPostProcessor:BeanDefinitionRegistry的后置处理器,在所有beanDefinition将要被加载时执行,可以对beanDefinition的属性进行修改
- BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的
流程总的来说有几下几个步骤:
- 首先处理开发者传进来的beanFactoryPostProcessors数组,循环执行postProcessBeanDefinitionRegistry
- 分三次从bdmap获取获取BeanDefinitionRegistryPostProcessor.class的bean,然后执行他们的postProcessBeanDefinitionRegistry方法 用于注册bd
- 第一次获取的bd是ConfigurationClassPostProcessor,然后执行它的postProcessBeanDefinitionRegistry方法,将被@Component注解的类变成bd加入bdmap中
- 第二次接着从bdmap中找出实现了BeanDefinitionRegistryPostProcessor的bd,因为经过扫描包后bdmap已经变化了,再从此时的bdmap中找出BeanDefinitionRegistryPostProcessor类型并实现了ordered接口的bd,然后再执行他们的postProcessBeanDefinitionRegistry方法
- 最后是不断的寻找是否还有未执行的BeanDefinitionRegistryPostProcessor类型的bd,并执行postProcessBeanDefinitionRegistry方法
- 找出所有实现BeanFactoryPostProcessor接口的类
- 将所有实现BeanFactoryPostProcessor接口的类按实现PriorityOrdered、Ordered和其他分成三类,然后依次执行他们的postProcessBeanFactory方法;
1-2步主要是在beanFactory刚初始化后,进行扫描包、扫描配置文件,并且注册beanDefinition
3-4步主要是在bd被注册完成后,对bdmap中的bd进行一些修改操作;
在执行过程中,beanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor的bean都是通过beanFactory.getBean 方法获取,也就是在执行这个方法时创建了他们的实例;
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//存放所有实现了BeanFactoryPostProcessor接口的实例
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//存放所有已经执行的实现BeanDefinitionRegistryPostProcessors接口的实例
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
//先处理自定义的BeanDefinitionRegistryPostProcessor bd,并执行postProcessBeanDefinitionRegistry方法
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
//BeanFactoryPostProcessor bd先保存
regularPostProcessors.add(postProcessor);
}
}
// 分3次 从bdmap中获取BeanDefinitionRegistryPostProcessor.class的bean,然后执行他们的postProcessBeanDefinitionRegistry方法 用于注册bd
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 第一次获取的bd是ConfigurationClassPostProcessor,然后执行它的postProcessBeanDefinitionRegistry方法,将被@Component注解的类变成bd加入bdmap中
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 第二次接着从bdmap中找出实现了BeanDefinitionRegistryPostProcessor的bd,因为经过扫描包后bdmap已经变化了,再从此时的bdmap中找出BeanDefinitionRegistryPostProcessor类型并实现了ordered接口的bd,然后再执行他们的postProcessBeanDefinitionRegistry方法
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 最后是不断的寻找是否还有未执行的BeanDefinitionRegistryPostProcessor类型的bd,并执行postProcessBeanDefinitionRegistry方法
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 最后执行所有已发现的BeanDefinitionRegistryPostProcessor类型的bd 对bd内容进行修改
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 找出所有实现BeanFactoryPostProcessor接口的类
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 将所有实现BeanFactoryPostProcessor接口的类按实现PriorityOrdered、Ordered和其他分成三类存放
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
//跳过已执行的
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName
orderedPostProcessorNames.add(ppName);
}
else {
// 添加剩下的普通BeanFactoryPostProcessor的beanName
nonOrderedPostProcessorNames.add(ppName);
}
}
// 1. 调用所有实现PriorityOrdered接口的BeanFactoryPostProcessor的postProcessBeanFactory方法
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 2. 调用所有实现Ordered接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// 3. 调用所有实现Ordered接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// 清理缓存
beanFactory.clearMetadataCache();
}
第一次获取的BeanDefinitionRegistryPostProcessor,进行包扫描
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
//储存配置类bean
String[] candidateNames = registry.getBeanDefinitionNames();
//找到作为配置类的启动类加入到configCandidates
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {
return;
}
// Sort by previously determined @Order value, if applicable
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
//如果是单例模式 获取beanNameGenerator
// Detect any custom bean name generation strategy supplied through the enclosing application context
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
//获取一个配置类的解析器
// Parse each @Configuration class
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
//解析配置类 根据配置类的配置进行扫描包、注册、解析@Bean等功能 解析后将配置类放入configurationClasses集合中
parser.parse(candidates);
parser.validate();
//获得configurationClasses集合 这个集合可以获取配置类对应的ConfigurationClass和BeanMethod集合
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 注册 @Import和@Bean的beanDefinition
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
// 从已经注册的bd中找到还没有解析过的bd,再进行循环解析,例如@Bean的方法就可能是一个配置类
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
解析配置类并注册bd
这个方法按顺序依次做了几件事:
- 处理成员内部类
- 处理@PropertySources:加载Resource资源,并添加到Environment环境中;
- 处理@ComponentScan:扫描包并注册BeanDefinition;
- 处理@Import:处理ImportSelector 的实现类和ImportBeanDefinitionRegistrar 的实现类,普通类则当作配置类进行解析;
- @ImportResource:获取需要导入的资源配置信息,将这些配置信息添加至 ConfigurationClass.importedResources集合中
- 处理@Bean:将带有@Bean的方法封装成BeanMethod并保存到ConfigurationClass.beanMethods集合中;
- 处理接口Bean
- 如果有父类:则循环进行解析
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
//1. 如果当前类含有@Component的属性的内部成员类,则处理内部类
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
//递归的处理成员类 最终调用的还是doProcessConfigurationClass
processMemberClasses(configClass, sourceClass);
}
//2. 如果有@PropertySources 则先进行处理
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
//3. 处理@ComponentScan 进行包扫描
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
// 如果配置类包含@ComponentScan注解,立即执行包扫描
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
//接下来递归的去对已扫描的beanDefinition进行parse,因为有可能有的class有@ComponentScan或@ComponentScans,又或者由@Configuration注解
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
//判断是否是一个配置类
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// 4. 处理@Import注解注册的bean 这一步只会将import注册的bean变为ConfigurationClass 不会变成BeanDefinition
// 而是在loadBeanDefinitions()方法中变成BeanDefinition,再放入到BeanDefinitionMap中
processImports(configClass, sourceClass, getImports(sourceClass), true);
// 5. 处理@ImportResource引入的配置文件
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// 6. 处理@Bean的方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
//7. 处理接口
// Process default methods on interfaces
processInterfaces(configClass, sourceClass);
//8. 如果有父类,则循环进行解析
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
}
}
//处理
// No superclass -> processing is complete
return null;
}
包扫描
- 先通过parse方法解析@Component的属性,来设定scanner
- 如果basePackages是空的,就使用当前配置类所在的根目录进行包扫描(这就能解释为什么启动类应该和别的类在同一个包下,并且basePackages一旦设定就会缩小包扫描范围)
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
BeanUtils.instantiateClass(generatorClass));
//通过@ComponentScan属性配置ClassPathBeanDefinitionScanner
ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
scanner.setScopedProxyMode(scopedProxyMode);
}
else {
Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
}
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
//添加包含过滤器 其中最常见的TypeFilter有AnnotationTypeFilter、AssignableTypeFilter,符合条件则保留,默认的有@Component和@ManageBean的包含过滤器
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addIncludeFilter(typeFilter);
}
}
//排除过滤器,用于将已扫描的bean过滤
for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addExcludeFilter(typeFilter);
}
}
//配置懒加载
boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
}
Set<String> basePackages = new LinkedHashSet<>();
//通过basePackages属性获取包扫描目录
String[] basePackagesArray = componentScan.getStringArray("basePackages");
for (String pkg : basePackagesArray) {
String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
Collections.addAll(basePackages, tokenized);
}
for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
}
//如果basePackages是空的,就通过当前配置类所在的目录进行扫描
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(declaringClass));
}
// 扫描过滤器
scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
@Override
protected boolean matchClassName(String className) {
return declaringClass.equals(className);
}
});
// 正式开始包扫描
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
doScan是扫描和生成注册beanDefinition的方法
rotected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
// 扫描basePackage下的所有资源,并将符合条件的资源以beanDefinition的形式返回
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
// 主要包括bean的scope属性(默认单例)以及代理策略(不需要代理,JDK动态代理、CGLIB)
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
// 设定scop
candidate.setScope(scopeMetadata.getScopeName());
// 生成beanName
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
// 根据beanDefinitionDefaults设置一些默认值
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
// 解析@Scope、@Primary、@Lazy等属性并设置到BeanDefinition中
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
// 检查BeanDefinition 主要检查这个容器中是否已经存在此BeanDefinition
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
//设置代理策略
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
//注册到spring容器中
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
下面这个方法就是去扫描包下的@component
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
// 先生成扫描的classPattern = classpath*:(basePackage的相对位置)/**/*.class,如classpath*:com/ljq/mymbg/**/*.class
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
// 使用getResources去获取basePackage下的所有class资源或jar
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
// 扫描所有的资源 对resource做一些条件过滤,将符合条件的resource转换成ScannedGenericBeanDefinition
for (Resource resource : resources) {
if (traceEnabled) {
logger.trace("Scanning " + resource);
}
if (resource.isReadable()) {
try {
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
//根据excludeFilters、excludeFilters初步筛选 如是否被@Component或@ManagedBean标注,是否已经被扫描过
if (isCandidateComponent(metadataReader)) {
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
sbd.setSource(resource);
// 这里会再有一个筛选条件,一般是根据类文件的元数据筛选,如是不是具体类,是不是顶层类,是不是抽象类等
// 默认情况下只添加顶层的具体类,顶层的意思是可以独立实例化而不会依赖外部类
// 成员内部类需要外部类对象才能实例化,就不会通过。
if (isCandidateComponent(sbd)) {
if (debugEnabled) {
logger.debug("Identified candidate component class: " + resource);
}
candidates.add(sbd);
}
else {
if (debugEnabled) {
logger.debug("Ignored because not a concrete top-level class: " + resource);
}
}
}
else {
if (traceEnabled) {
logger.trace("Ignored because not matching any filter: " + resource);
}
}
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to read candidate component class: " + resource, ex);
}
}
else {
if (traceEnabled) {
logger.trace("Ignored because not readable: " + resource);
}
}
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
}
return candidates;
}
getResources方法会调用findPathMatchingResources方法,这里会根据资源的属性(jar包、bundle或class资源)选择不同的读取方式
protected Resource[] findPathMatchingResources(String locationPattern) throws IOException {
String rootDirPath = determineRootDir(locationPattern);
String subPattern = locationPattern.substring(rootDirPath.length());
Resource[] rootDirResources = getResources(rootDirPath);
Set<Resource> result = new LinkedHashSet<>(16);
for (Resource rootDirResource : rootDirResources) {
rootDirResource = resolveRootDirResource(rootDirResource);
URL rootDirUrl = rootDirResource.getURL();
if (equinoxResolveMethod != null && rootDirUrl.getProtocol().startsWith("bundle")) {
URL resolvedUrl = (URL) ReflectionUtils.invokeMethod(equinoxResolveMethod, null, rootDirUrl);
if (resolvedUrl != null) {
rootDirUrl = resolvedUrl;
}
rootDirResource = new UrlResource(rootDirUrl);
}
if (rootDirUrl.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {
result.addAll(VfsResourceMatchingDelegate.findMatchingResources(rootDirUrl, subPattern, getPathMatcher()));
}
else if (ResourceUtils.isJarURL(rootDirUrl) || isJarResource(rootDirResource)) {
result.addAll(doFindPathMatchingJarResources(rootDirResource, rootDirUrl, subPattern));
}
else {
result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern));
}
}
if (logger.isTraceEnabled()) {
logger.trace("Resolved location pattern [" + locationPattern + "] to resources " + result);
}
return result.toArray(new Resource[0]);
}
findPathMatchingResources会调用最终实现扫描包的方法doRetrieveMatchingFiles,这个方法递归的去检索包下的class文件,并将他们添加到result set,并经过一系列处理,最终返回的是一个FileSystemResource数组
protected void doRetrieveMatchingFiles(String fullPattern, File dir, Set<File> result) throws IOException {
if (logger.isTraceEnabled()) {
logger.trace("Searching directory [" + dir.getAbsolutePath() +
"] for files matching pattern [" + fullPattern + "]");
}
for (File content : listDirectory(dir)) {
String currPath = StringUtils.replace(content.getAbsolutePath(), File.separator, "/");
if (content.isDirectory() && getPathMatcher().matchStart(fullPattern, currPath + "/")) {
if (!content.canRead()) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping subdirectory [" + dir.getAbsolutePath() +
"] because the application is not allowed to read the directory");
}
}
else {
doRetrieveMatchingFiles(fullPattern, content, result);
}
}
if (getPathMatcher().match(fullPattern, currPath)) {
result.add(content);
}
}
}
@Import处理:配置导入
如果类含有@Import注解,则需要执行processImports方法来导入配置文件,其根据@import里的类型执行不同的逻辑
- 实现了ImportSelector接口的类:调用selectImports方法(),得到要注入的类的全限定名。根据类全限定名,得到类元信息。然后递归的调用processImports方法
- 实现了ImportBeanDefinitionRegistrar接口的类:会实例化这个类,放入集合importBeanDefinitionRegistrars当中
- 普通类型的类:那么就把它当作是配置类来处理,调用processConfigurationClass方法,最终会放入到configurationClasses这个集合当中
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, boolean checkForCircularImports) {
if (importCandidates.isEmpty()) {
return;
}
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
//importStack是一个继承了ImportRegistry 内部是一个multivalueMap
this.importStack.push(configClass);
try {
//循环处理需要import的资源
for (SourceClass candidate : importCandidates) {
// 1. 如果import的是ImportSelector.class实现类
if (candidate.isAssignable(ImportSelector.class)) {
Class<?> candidateClass = candidate.loadClass();
// 使用ImportSelector.class初始化candidateClass
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
ParserStrategyUtils.invokeAwareMethods(
selector, this.environment, this.resourceLoader, this.registry);
// 如果selector是DeferredImportSelector对象 加入importStack队列
if (selector instanceof DeferredImportSelector) {
this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
}
// 如果selector是DeferredImportSelector的实现类,则进行相应处理 !! 就是在这里执行启动类引入的AutoConfigurationImportSelector.class.selectImports方法
else {
// 执行selectImports方法,这个方法会返回需要import的className数组
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
// 将className数组转为SourceClass数组
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
// 递归执行,因为SourceClass数组中可能是ImportSelector或ImportBeanDefinitionRegistrar
processImports(configClass, currentSourceClass, importSourceClasses, false);
}
}
// 2. 如果是ImportBeanDefinitionRegistrar.class的实现类
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
Class<?> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar =
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
ParserStrategyUtils.invokeAwareMethods(
registrar, this.environment, this.resourceLoader, this.registry);
//放到当前类对应的configurationClass的importBeanDefinitionRegistrars map里
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
// process it as an @Configuration class
//3. 如果是普通类 则将其加入importStack队列,并且按配置文件来解析,执行processConfigurationClass,类中的@Bean和@Component内部类会被先解析,其自身会被先放到configurationClasses这个集合中
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
processConfigurationClass(candidate.asConfigClass(configClass));
}
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configClass.getMetadata().getClassName() + "]", ex);
}
finally {
this.importStack.pop();
}
}
}
这个方法没有将import的class对应的beanDefinition注册到bdmap中,而是解析成了ConfigurationClass放到了ConfigurationClass.importedResources集合中;
@Bean方法处理:
处理@Bean的入口在doProcessConfigurationClass方法中:
//通过ASM解析出所有带有@Bean注解的方法,并且放入beanMethods中
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
//将这些方法封装成BeanMethod对象并且保存到ConfigurationClass.beanMethods集合中
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
@Bean处理结束后,带有@Bean注解的方法被封装成BeanMethod对象并且保存到ConfigurationClass.beanMethods集合中;
@Bean接口处理:
jdk8后,允许接口的方法有默认的实现方法
private void processInterfaces(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
for (SourceClass ifc : sourceClass.getInterfaces()) {
//获得所有带有@Bean的方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(ifc);
for (MethodMetadata methodMetadata : beanMethods) {
if (!methodMetadata.isAbstract()) {
// A default method or other concrete method on a Java 8+ interface...
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
}
processInterfaces(configClass, ifc);
}
}
注册@Bean和@Import的bd
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
//注册所有configurationClass对应的bean
for (ConfigurationClass configClass : configurationModel) {
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
接下来是解析configuration的方法
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
//通过@Conditional做一些过滤操作
if (trackedConditionEvaluator.shouldSkip(configClass)) {
String beanName = configClass.getBeanName();
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
this.registry.removeBeanDefinition(beanName);
}
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
return;
}
// 如果当前配置类是被@Import注入的,则注册自己
if (configClass.isImported()) {
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
// 将@Bean方法注册为BeanDefinition
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
// 将configClass中ImportResource指定的资源注册为BeanDefinition
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
// 如果该类有@Import,且Import进来的类实现了ImportBeanDefinitionRegistrar接口,则调用Import进来的类的registerBeanDefinitions方法
// mybatis继承spring就是基于这个实现 -> MapperScannerRegistrar
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
注册@Import的bean
private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {
AnnotationMetadata metadata = configClass.getMetadata();
// 创建一个bd对象
AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);
ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);
configBeanDef.setScope(scopeMetadata.getScopeName());
// bean的名称
String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);
// 配置信息
AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 注册bean
this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());
configClass.setBeanName(configBeanName);
if (logger.isTraceEnabled()) {
logger.trace("Registered bean definition for imported class '" + configBeanName + "'");
}
}
注册@Bean的bean
- 获取@Bean注解元信息
- 创建ConfigurationClassBeanDefinition 对象
- 根据注解元信息,方法的静态非静态对bd进行配置;
- 注册bd;
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
ConfigurationClass configClass = beanMethod.getConfigurationClass();
MethodMetadata metadata = beanMethod.getMetadata();
String methodName = metadata.getMethodName();
//通过@Conditional进行过滤
if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {
configClass.skippedBeanMethods.add(methodName);
return;
}
if (configClass.skippedBeanMethods.contains(methodName)) {
return;
}
// 获得@Bean注解元信息
AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
Assert.state(bean != null, "No @Bean annotation attributes");
// Consider name and any aliases
List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
String beanName = (!names.isEmpty() ? names.remove(0) : methodName);
// Register aliases even when overridden
for (String alias : names) {
this.registry.registerAlias(beanName, alias);
}
// Has this effectively been overridden before (e.g. via XML)?
if (isOverriddenByExistingDefinition(beanMethod, beanName)) {
if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) {
throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(),
beanName, "Bean name derived from @Bean method '" + beanMethod.getMetadata().getMethodName() +
"' clashes with bean name for containing configuration class; please make those names unique!");
}
return;
}
ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);
beanDef.setResource(configClass.getResource());
beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));
// 如果方法是静态的:
// 直接设置 `beanClassName` 和 `factoryMethodName` 属性,通过这两者就可以创建当前方法 Bean 对象
if (metadata.isStatic()) {
// static @Bean method
beanDef.setBeanClassName(configClass.getMetadata().getClassName());
beanDef.setFactoryMethodName(methodName);
}
// 如果方法是成员方法:
// 则设置 `factoryBeanName` 和 `factoryMethodName` 属性
// 和静态方法不同,成员方法的class bean需要先被初始化,然后调用该方法创建当前方法bean对象
else {
// instance @Bean method
beanDef.setFactoryBeanName(configClass.getBeanName());
beanDef.setUniqueFactoryMethodName(methodName);
}
//设置注入模式为构造器注入,因为方法可能带有参数,需要注入
beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
beanDef.setAttribute(org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.
SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);
AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);
Autowire autowire = bean.getEnum("autowire");
// 如果设置了注入模式,则覆盖上面的构造器注入模式
if (autowire.isAutowire()) {
beanDef.setAutowireMode(autowire.value());
}
boolean autowireCandidate = bean.getBoolean("autowireCandidate");
if (!autowireCandidate) {
beanDef.setAutowireCandidate(false);
}
// 如果配置了 `initMethod`,则设置初始化方法名称
String initMethodName = bean.getString("initMethod");
if (StringUtils.hasText(initMethodName)) {
beanDef.setInitMethodName(initMethodName);
}
// 如果配置了 `destroyMethod`,则设置销毁方法名称
String destroyMethodName = bean.getString("destroyMethod");
beanDef.setDestroyMethodName(destroyMethodName);
// 如果配置了 @Scope 注解,则进行相关配置
ScopedProxyMode proxyMode = ScopedProxyMode.NO;
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class);
if (attributes != null) {
beanDef.setScope(attributes.getString("value"));
proxyMode = attributes.getEnum("proxyMode");
if (proxyMode == ScopedProxyMode.DEFAULT) {
proxyMode = ScopedProxyMode.NO;
}
}
// Replace the original bean definition with the target one, if necessary
BeanDefinition beanDefToRegister = beanDef;
if (proxyMode != ScopedProxyMode.NO) {
BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(
new BeanDefinitionHolder(beanDef, beanName), this.registry,
proxyMode == ScopedProxyMode.TARGET_CLASS);
beanDefToRegister = new ConfigurationClassBeanDefinition(
(RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata);
}
if (logger.isTraceEnabled()) {
logger.trace(String.format("Registering bean definition for @Bean method %s.%s()",
configClass.getMetadata().getClassName(), beanName));
}
this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}
注册@ImportResource的Bean
主要是解析XML文件
private void loadBeanDefinitionsFromImportedResources(
Map<String, Class<? extends BeanDefinitionReader>> importedResources) {
Map<Class<?>, BeanDefinitionReader> readerInstanceCache = new HashMap<>();
importedResources.forEach((resource, readerClass) -> {
// Default reader selection necessary?
if (BeanDefinitionReader.class == readerClass) {
if (StringUtils.endsWithIgnoreCase(resource, ".groovy")) {
// When clearly asking for Groovy, that's what they'll get...
readerClass = GroovyBeanDefinitionReader.class;
}
else {
// Primarily ".xml" files but for any other extension as well
readerClass = XmlBeanDefinitionReader.class;
}
}
BeanDefinitionReader reader = readerInstanceCache.get(readerClass);
if (reader == null) {
try {
// Instantiate the specified BeanDefinitionReader
reader = readerClass.getConstructor(BeanDefinitionRegistry.class).newInstance(this.registry);
// Delegate the current ResourceLoader to it if possible
if (reader instanceof AbstractBeanDefinitionReader) {
AbstractBeanDefinitionReader abdr = ((AbstractBeanDefinitionReader) reader);
abdr.setResourceLoader(this.resourceLoader);
abdr.setEnvironment(this.environment);
}
readerInstanceCache.put(readerClass, reader);
}
catch (Throwable ex) {
throw new IllegalStateException(
"Could not instantiate BeanDefinitionReader class [" + readerClass.getName() + "]");
}
}
// TODO SPR-6310: qualify relative path locations as done in AbstractContextLoader.modifyLocations
reader.loadBeanDefinitions(resource);
});
}
通过ImportBeanDefinitionRegistrar实现类注册Bean
private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
registrars.forEach((registrar, metadata) ->
registrar.registerBeanDefinitions(metadata, this.registry));
}
注册BeanPostProcessor
注册BeanPostProcessor,这个后置处理器在bean初始化前后触发;
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// 按实现priorityOrdered、order、其他的类型将BeanPostProcessor分成三类
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 1. 首先注册实现了priorityOrdered的BeanPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 2. 然后注册实现了Ordered的BeanPostProcessor
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 3. 注册所有剩余的BeanPostProcessor
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 最后重新注册所有内部BeanPostProcessor
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 注册ApplicationListenerDetector。用来检测bean是否是ApplicationListener,如果是判断是否是单例,如果不是单例,那么删除singtonNames中对应的key
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
初始化context的信息源和广播器
初始化信息源
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isTraceEnabled()) {
logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
}
}
}
初始化广播器
- 首先判断beanFactory容器中是否存在这个广播器:applicationEventMulticaster;如果存在,则用beanFactory中的bean;
- 如果不存在则使用新建SimpleApplicationEventMulticaster
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isTraceEnabled()) {
logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
}
}
}
扩展方法:初始化特殊bean
这个方法在初始化bean之前执行,可以对其进行重写以拓展
protected void onRefresh() throws BeansException {
// For subclasses: do nothing by default.
}
注册监听器
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
初始化Bean
这个方法实现了所有剩余单例bean的初始化,所有的非懒加载的单例都会被创建实例并注册;
执行流程:
- 初始化上下文的转换服务,ConversionService是一个类型转换的接口
- 初始化LoadTimeWeaverAware接口的bean
- 停止使用时间加载器
- 缓存所有的beanDefinition,并之后不能被改变
- 实例化所有非懒加载的单例bean
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化上下文的转换服务,ConversionService是一个类型转换的接口
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 初始化LoadTimeWeaverAware接口的bean
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 停止使用时间加载器
beanFactory.setTempClassLoader(null);
//缓存所有的beanDefinition,并之后不能被改变
beanFactory.freezeConfiguration();
// 实例化所有非懒加载的单例bean
beanFactory.preInstantiateSingletons();
}
缓存所有的beanDefinition
public void freezeConfiguration() {
this.configurationFrozen = true;
this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
}
执行结束后用一个String数组frozenBeanDefinitionNames储存所有bd的name
初始化bean
所有non-lazy且singleton的bean都在这里被加载,这里有两种bean类型:bean、factoryBean
什么是factoryBean:
-
factoryBean是用来创建bean的bean,通常用于创建同属一类的bean;
-
public interface FactoryBean<T> { @Nullable // 用于获取传入泛型的实例bean T getObject() throws Exception; @Nullable // 获取T的类型 Class<?> getObjectType(); // 用于规定factory创建的bean是否是单例 default boolean isSingleton() { return true; } }
初始化bean的入口preInstantiateSingletons
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// copy一个bdnames数组
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 加载所有的non-lazy & singleton bean
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 如果不是抽象的、是单例和非懒加载的则进行初始化
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 如果是factoryBean则通过factoryBean获取对象实例
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
获取bean的方法:doGetBean
**mergedBeanDefinition:**是一个概念上的BeanDefinition,本身类型还是RootBeanDefinition,因为有些类有继承关系,所以用remerge来将父类的信息与子类的信息合并到一起,合成一个新的bd,就是MergedBeanDefinition了
主要执行流程:
- 如果缓存中有bean,则直接返回
- 如果当前beanFactory没有这个bd,且fatherBeanFactory不为null,则通过fatherBeanFactory来创建bd
- 先初始化依赖的bean并检查循环依赖
- 根据scope创建bean
- singleton:使用getSingleton方法并实现ObjectFactory的getObject方法创建bean实例
- prototype:使用createBean创建实例
- 其他scope:使用scope的get方法并实现ObjectFactory的getObject方法创建bean实例
- 检查创建的bean的类型是否与需要的类型一致,不一致则进行类型转换
- 返回bean对象
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 解析beanName,主要是解析别名、去掉FactoryBean的前缀“&”
final String beanName = transformedBeanName(name);
Object bean;
// 如果缓存中有bean,则直接返回
// 三级缓存:
// 1. 从singletonObjects cache获取单例
// 2. 获取不到则从earlySingletonObjects获取
// 3. 还是获取不到则从singletonFactories通过getObject()获取,如果获取到则从singletonFactories移除,放入earlySingletonObjects中
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 返回beanName对应的实例对象(主要用于FactoryBean的特殊处理,普通Bean会直接返回sharedInstance本身)
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 判断是否有循环依赖,如果beanName已经正在创建Bean实例中,而此时我们又要再一次创建beanName的实例,则代表出现了循环依赖,需要抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 如果父beanFactory存在 且当前factory不存在bd,则通过父beanFactory来获取bean实例
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 将别名解析成真正的beanName
String nameToLookup = originalBeanName(name);
// 尝试到父beanFactory获取bean对象
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
// 到这一步说明这个bean实例需要通过当前的beanFactory创建,在这里将beanName放入alreadyCreated缓存,主要是为了检查循环依赖问题
// 这里会re-merge一次beanDefinition
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// re-merge一次bd并检查
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 实例化依赖bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 检查是否循环依赖
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 将依赖关系注册到缓存中
registerDependentBean(dep, beanName);
try {
// 初始化依赖的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 针对不同的scope进行bean的创建
// 1. singleton的bean
if (mbd.isSingleton()) {
// getSingleton的第二个参数是一个ObjectFactory,这里重写了他的getObject方法
sharedInstance = getSingleton(beanName, () -> {
try {
// 创建bean的实例
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
// 返回beanName对应的实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 2. prototype的bean
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
// 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
beforePrototypeCreation(beanName);
// 创建Bean实例
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 将创建完的beanName从prototypesCurrentlyInCreation缓存中移除
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 3. 其他scope的bean 可能是request之类的
else {
String scopeName = mbd.getScope();
// 根据scopeName,从缓存拿到scope实例
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
// 通过scope获取实例,同样新建一个ObjectFactory 并且重写了getObject方法
Object scopedInstance = scope.get(beanName, () -> {
// 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
beforePrototypeCreation(beanName);
try {
// 创建Bean实例
return createBean(beanName, mbd, args);
}
finally {
// 将创建完的beanName从prototypesCurrentlyInCreation缓存中移除
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 检查所需类型是否与实际的bean对象的类型匹配, 如果类型不一样,则尝试类型转换
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
创建Bean的方法:createBean
- 获取bean的类型
- 执行BeanPostProcessors后置处理器的方法,可以在这扩展实现代理对象的功能;
- 使用doCreateBean方法创建bean
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 将bean解析为类引用并放入bd中
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 验证以及准备需要覆盖的方法
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 给BeanPostProcessors 一个机会来返回代理对象来代替真正的实例,在这里实现创建代理对象功能.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 创建bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
doCreateBean方法就是spring创建bean的实际方法了
- 先从factoryBeanInstanceCache缓存中尝试获取,如果是单例的首先清除缓存
- 实例化bean,使用BeanWarpper包装
- 如果存在工厂方法,则使用工厂方法实例化
- 如果有多个构造函数,则根据传入的参数确定构造函数进行初始化
- 使用默认的构造函数初始化
- 应用MergedBeanDefinitionPostProcessor,Autowired注解就是在这样完成的解析工作
- 依赖处理。如果A和B存在循环依赖,那么Spring在创建B的时候,需要自动注入A时,并不会直接创建再次创建A,而是通过放入缓存中A的ObjectFactory来创建实例,这样就解决了循环依赖的问题
- 属性填充。所有需要的属性都在这一步注入到bean
- 循环依赖检查
- 注册DisposableBean。如果配置了destroy-method,这里需要注册,以便在销毁时调用
- 完成创建并返回
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 先从factoryBeanInstanceCache缓存中尝试获取
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 如果缓存中不存在,则根据bean对应的策略创建新的实例,如:工厂方法、构造器自动注入、简单初始化
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 应用MergedBeanDefinitionPostProcessor 后处理器,合并bean的定义信息
// Autowire等注解信息就是在这一步完成预解析,并且将注解需要的信息放入缓存
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// 是否需要提前曝光=单例&允许循环依赖&bean正在创建中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 为了避免循环依赖,在bean初始化完成前,就将创建bean实例的ObjectFactory放入工厂缓存(singletonFactories)
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 对bean属性进行填充,注入bean中的属性,会递归初始化依赖的bean
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
// 调用初始化方法,比如init-method、注入Aware对象、应用后处理器
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
// 从提前曝光的bean缓存中查询bean,目的是验证是否有循环依赖存在
// 如果存在循环依赖,也就是说该bean已经被其他bean递归加载过,放入了提早曝光的bean缓存中
Object earlySingletonReference = getSingleton(beanName, false);
// 只有检测到循环依赖的情况下,earlySingletonReference才不会为null
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// 检测依赖
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
//将未创建的依赖加入actualDependentBeans中
actualDependentBeans.add(dependentBean);
}
}
// actualDependentBeans不为空,说明其依赖的bean并没有被创建完,而bean创建之前其依赖的bean一定先被创建,说明此时存在循环依赖
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// 根据scope注册bean
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
创建实例方法:createBeanInstance
执行的大概流程为:
- 如果bean定义中存在 InstanceSupplier ,会使用这个回调接口创建对象(应该是3.X以后新加的,3.X的源码中没有)
- 根据配置的factoryMethodName或factory-mtehod创建bean
- 解析构造函数并进行实例化
因为一个类可能有多个构造函数,所以需要根据配置文件中配置的参数或者传入的参数确定最终调用的构造函数。因为判断过程会比较消耗性能,所以Spring会将解析、确定好的构造函数缓存到BeanDefinition中的resolvedConstructorOrFactoryMethod字段中。在下次创建相同bean的时候,会直接从RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod缓存的值获取,避免再次解析。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
// 尝试通过supplier创建对象实例 supplier是一个主动创建对象的callback方法,比反射创建对象的效率更高
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 尝试通过工厂方法创建对象实例
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 如果beanDefinition的参数列表为空,则使用默认构造器创建实例
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
// mbd.constructorArgumentsResolved 是一个标志 在使用构造器创建实例后,Spring会将解析过后确定下来的构造器或工厂方法保存在缓存中,避免再次创建相同bean时再次解析
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
// 已经解析过class的构造器,使用已经解析好的构造器
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 使用默认构造器
return instantiateBean(beanName, mbd);
}
}
// 需要根据参数解析、确定构造函数
// 使用AutowiredAnnotationBeanPostProcessor获得构造器列表
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// 解析的构造器不为空 || 注入类型为构造函数自动注入 || bean定义中有构造器参数 || 传入参数不为空
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 构造函数自动注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 使用默认构造器
return instantiateBean(beanName, mbd);
}
获取构造器的前置处理器AutowiredAnnotationBeanPostProcessor:
AutowiredAnnotationBeanPostProcessor实现了BeanPostProcessor接口,是bean实例化前后调用的前后置处理器;
这里调用了他的determineCandidateConstructors方法,来获取bean的构造器,执行流程:
- 首先是检查是否有@Lookup的注解
- 然后检查@Autowired注解的构造器,有三种情况
- 构造器有被@Autowired注解,需要检查有没有别的构造器也被@Autowired注解,有则抛出异常,没有则设为requiredConstructor
- 构造器没有被@Autowired注解,且是有参构造器,跳过
- 构造器没有被@Autowired注解,但是是无参构造器,设为defaultConstructor
- 检查结束后,也有三种情况:
- 候选构造器不为空,但是requiredConstructor为null,就将无参构造器加入最终构造器列表
- 候选构造器为空,说明没有@Autowired注解的有参构造器,且没有无参构造器,但是当前类只有一个构造器,那么就将这个构造器加入最终构造器列表
- 候选构造器为空,类定义了多个构造器方法,且没有@Autowired,最终构造器列表为空
那么由这个方法可以总结出几点:
- 如果一个类只有一个无参构造器,那么最终会使用无参构造器进行注入
- 如果一个类只有一个有参构造器,那么最终会使用这个有参构造器进行注入
- 如果一个类有多个有参构造器,那么需要使用@Autowired告诉Spring应该使用哪个构造器进行注入
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
throws BeanCreationException {
// 在这里检查@Lookup的方法,
if (!this.lookupMethodsChecked.contains(beanName)) {
try {
ReflectionUtils.doWithMethods(beanClass, method -> {
Lookup lookup = method.getAnnotation(Lookup.class);
if (lookup != null) {
Assert.state(this.beanFactory != null, "No BeanFactory available");
LookupOverride override = new LookupOverride(method, lookup.value());
try {
RootBeanDefinition mbd = (RootBeanDefinition) this.beanFactory.getMergedBeanDefinition(beanName);
mbd.getMethodOverrides().addOverride(override);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(beanName,
"Cannot apply @Lookup to beans without corresponding bean definition");
}
}
});
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
}
this.lookupMethodsChecked.add(beanName);
}
// Quick check on the concurrent map first, with minimal locking.
Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
// Fully synchronized resolution now...
synchronized (this.candidateConstructorsCache) {
candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
Constructor<?>[] rawCandidates;
try {
// 反射获得构造函数
rawCandidates = beanClass.getDeclaredConstructors();
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
Constructor<?> requiredConstructor = null;
Constructor<?> defaultConstructor = null;
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
int nonSyntheticConstructors = 0;
// 遍历构造方法
for (Constructor<?> candidate : rawCandidates) {
//判断构造方法是否是合成的
if (!candidate.isSynthetic()) {
nonSyntheticConstructors++;
}
else if (primaryConstructor != null) {
continue;
}
// 查看是否有 @Autowired 注解
AnnotationAttributes ann = findAutowiredAnnotation(candidate);
// 第一次如果没有@Autowired注解,去找他的代理类
if (ann == null) {
// 这里是去找他的CGLIB代理子类的相同参数列表的构造器是否被@Autowired了
Class<?> userClass = ClassUtils.getUserClass(beanClass);
if (userClass != beanClass) {
try {
Constructor<?> superCtor =
userClass.getDeclaredConstructor(candidate.getParameterTypes());
ann = findAutowiredAnnotation(superCtor);
}
catch (NoSuchMethodException ex) {
// Simply proceed, no equivalent superclass constructor found...
}
}
}
// 如果有@Autowired
if (ann != null) {
// 检查是否已经有requiredConstructor,如果已经有说明之前已经有被@Autowired注解的有参构造器了,需要抛出异常
if (requiredConstructor != null) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
boolean required = determineRequiredStatus(ann);
if (required) {
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructors: " + candidates +
". Found constructor with 'required' Autowired annotation: " +
candidate);
}
// requiredConstructor接收这个构造器
requiredConstructor = candidate;
}
// 加入构造器列表
candidates.add(candidate);
}
//如果没有@Autowired且当前构造器是无参构造器,将当前构造器设为默认的构造器
else if (candidate.getParameterCount() == 0) {
defaultConstructor = candidate;
}
}
// 如果构造器列表仍为空
if (!candidates.isEmpty()) {
// 没有@Autowired的有参构造器
if (requiredConstructor == null) {
// 有无参构造器,则将默认构造器加入构造器列表
if (defaultConstructor != null) {
candidates.add(defaultConstructor);
}
else if (candidates.size() == 1 && logger.isInfoEnabled()) {
logger.info("Inconsistent constructor declaration on bean with name '" + beanName +
"': single autowire-marked constructor flagged as optional - " +
"this constructor is effectively required since there is no " +
"default constructor to fall back to: " + candidates.get(0));
}
}
candidateConstructors = candidates.toArray(new Constructor<?>[0]);
}
// 如果构造器仅有一个且为有参构造器,就将这个构造器加入列表
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
//
else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
}
else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
candidateConstructors = new Constructor<?>[] {primaryConstructor};
}
else {
candidateConstructors = new Constructor<?>[0];
}
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
有参构造:autowireConstructor
主要流程:
- 构造构造器执行参数列表:如果传入的参数列表是空的,需要在缓存和bd中获取参数;
- **获取构造器:**如果传入的构造器是null,则需要通过反射获取构造器列表并从中进行筛选;
- **创建实例:**通过1、2获取的构造器和构造器参数创建实例;
详细流程:
explicitArgs:getBean传入的参数列表
chosenCtors:getBean传入的构造器列表
- 尝试获取参数列表
- 如果explicitArgs不为空,那么就使用explicitArgs
- 如果explicitArgs为空,那么尝试从bd中加载参数
- 先尝试从缓存中获取
- 参数未完全解析,则进行参数解析
- 如果缓存中没有构造器或参数列表仍为null,则尝试获取构造器
- 如果chosenCtors不为空,则通过反射获取构造器列表
- 如果构造器列表只有一个构造器 & 构造器无参 & explicitArgs为空,则直接使用这个无参构造器构造实例,并且缓存构造器和参数列表
- 如果构造器列表不为null且有复数个构造器,则需要去筛选构造器
- 确定预选构造器参数数:
- 如果explicitArgs不为空,则通过explicitArgs确定参数数;
- 否则去解析xml配置文件,并且将解析得到的参数列表用resolvedValues接收;
- 遍历构造器列表,进行筛选,寻找最匹配的构造器:
- 如果当前构造器的参数数大于预选构造器参数数&当前已经找到构造器,结束循环
- if(当前构造器数参数数<预期构造器参数数) continue;
- 如果参数列表不为null:
- 从注解或使用参数名称探测器获取参数列表名称
- 根据类型和数据类型创建 参数持有者
- 参数列表为null,并且当前构造器参数数与explicitArgs的长度一致,则使用explicitArgs创建参数持有者
- 评价当前构造器与预期构造器的相似度
- 如果相似度比之前的构造器更高,则更新构造器,如果相似度相等,则记录;
- 已经找到构造器和对应的参数列表,创建实例并缓存构造器与参数列表
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
// 实例化BeanWrapper,是包装bean的容器
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
// 候选的构造函数列表和参数列表
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
// 构造函数最后确定使用的参数
Object[] argsToUse = null;
// 如果getBean中传入的参数不为空,那么就使用传入的参数
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
// 否则 尝试从 BeanDefinition 中加载缓存的bean构造时需要的参数
else {
Object[] argsToResolve = null;
// 先尝试从缓存中获取
synchronized (mbd.constructorArgumentLock) {
// 获取缓存中的构造器
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
// 如果构造函数不为空 && 构造函数参数已经解析
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// 从缓存中获取参数。这里如果不能获取到完全解析好的参数,则获取尚未解析的参数,进行解析后再赋值给 argsToUse
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
// preparedConstructorArguments 是尚未完全解析的构造函数参数
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
//如果缓存中存在 尚未完全解析的参数列表,则进行进一步的解析
if (argsToResolve != null) {
// 解析参数类型,如给定的参数列表为(int,int),这时就会将配置中的("1", "1") 转化为 (1,1)
// 缓存中的值可能是最终值,也可能是原始值,因为不一定需要类型转换
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
}
}
// 如果构造函数 和 构造函数入参都不为空,则可以直接生成bean。否则的话,需要通过一定的规则进行筛选
if (constructorToUse == null || argsToUse == null) {
// 获取候选的构造函数列表 chosenCtors一般通过AutowiredAnnotationBeanPostProcessor来获取
Constructor<?>[] candidates = chosenCtors;
// 如果获取不到则需要通过反射获取bean的构造函数集合
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
// 反射获取bean的构造参数集合
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
}
// 如果构造参数只有一个 且 getBean没有传参 且 构造参数无参。则无需继续筛选构造函数,直接使用唯一一个构造函数创建 BeanWrapper 并返回即可
if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Constructor<?> uniqueCandidate = candidates[0];
// 确认构造器无参 则进行构造实例
if (uniqueCandidate.getParameterCount() == 0) {
synchronized (mbd.constructorArgumentLock) {
// 将解析结果缓存
// 1. 缓存构造函数
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
// 2. 缓存标记
mbd.constructorArgumentsResolved = true;
// 3. 缓存构造参数
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
// 调用 instantiate 方法创建对象实例并保存到 bw中
bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
// 构造函数有多个并需要构造解析 需要进行解析
// mbd.getResolvedAutowireMode() 是针对 xml 注入的
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
// 解析出来的构造函数的参数个数
int minNrOfArgs;
// 如果getBean有传入参数 那么参数个数直接使用这个参数
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
// 获取xml配置文件中的配置的构造函数参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
// 用于承载解析后的构造函数参数的值
resolvedValues = new ConstructorArgumentValues();
// 这一步主要是做类型转换,因为xml配置中的参数值都是以字符串的形式保存的,因此需要对这些参数值进行类型转换,解析后的参数放入resolvedValues中,不拓展
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
// 寻找最匹配的构造函数
// 对构造函数列表进行排序: public 构造函数优先参数数量降序,非public构造函数参数数量降序
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
// 遍历构造函数,寻找合适的构造函数
for (Constructor<?> candidate : candidates) {
// 获取当前构造函数参数个数
Class<?>[] paramTypes = candidate.getParameterTypes();
// 如果已经找到选用的构造函数 (argstoUse != null) 或者 需要的构造函数的参数个数 小于 当前构造函数参数个数 则终止
if (constructorToUse != null && argsToUse != null && argsToUse.length > paramTypes.length) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
// 参数数量不相等,跳过
if (paramTypes.length < minNrOfArgs) {
continue;
}
// 到这里说明尚未找到构造函数,且目前的构造函数参数个数大于或等于构造函数参数个数,下面要对类型进行比较
ArgumentsHolder argsHolder;
// 如果xml解析得到的参数的值不为空
if (resolvedValues != null) {
try {
// 从 @ConstructorProperties 注解上获取参数名称数组
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
// 为null则说明没有使用注解
if (paramNames == null) {
// 获取参数名称探索器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
// 获取当前构造函数的参数名称数组
paramNames = pnd.getParameterNames(candidate);
}
}
// 这里会调用 DefaultListableBeanFactory#resolveDependency 方法来解析依赖关系
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}
else {
// 如果当前构造器的参数长度与getBean传的参数长度不一致,则跳过
if (paramTypes.length != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}
// 探测是否有不确定性的构造函数存在,例如不同构造函数的参数为父子关系
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// 如果他是当前最接近匹配则选择作为构造函数,因为可能有多个构造函数都同时满足, 选择最合适的(typeDiffWeight 最小的)作为最终构造函数
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
// 如果 已经找到候选构造函数,且当前这个构造函数也有相同的类似度则保存到 ambiguousConstructors 中。后面用于抛出异常
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
// 如果到这还无法找到构造函数,则查找构造函数失败,抛出异常
if (constructorToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
// // 如果ambiguousConstructors 不为空说明有多个构造函数可适配,并且 如果不允许多个存在,则抛出异常
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}
// 将解析的构造函数加入缓存
if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
Assert.state(argsToUse != null, "Unresolved constructor arguments");
// 构建实力并加入BeanWrapper中
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
**无参构造器:**instantiateBean
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
// 安全验证
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// 如果当前bean中的方法没有都没有被重写,则直接反射就好了
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
// 先通过缓存获取
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
// 通过反射获取无参构造器
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 通过无参构造器创建bean
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
**依赖填充的方法:**populateBean
在createBeanInstance后,Bean只是有了一个实例,但是还没有注入他的依赖,依赖一般由xml或者注解规定,populateBean方法就是在bean的实例刚被创建后执行,用来注入依赖;
spring大部分情况是通过调用AutowiredAnnotationBeanPostProcessor的postProcessProperties方法实现注入的;
主要的执行流程:
- 在注入依赖前,给InstantiationAwareBeanPostProcessors一次机会修改bean,如果返回了false,则不继续下面的步骤;
- 如果bean配置了依赖注入的模式,则执行下面两种自动装配方法:
- 根据type注入
- 根据name注入
- 调用AutowiredAnnotationBeanPostProcessor的postProcessProperties方法实现注入
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
boolean continueWithPropertyPopulation = true;
// 在这给了InstantiationAwareBeanPostProcessors一次机会修改bean,这个后置处理器在bean属性填充前调用
// 具体通过调用postProcessAfterInstantiation方法,如果调用返回false,表示不必继续进行依赖注入,直接返回
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
// 获取依赖值
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 根据Bean配置的依赖注入方式完成注入,默认是0,即不走以下逻辑,所有的依赖注入都需要在xml文件中有显式的配置
// 如果设置了相关的依赖装配方式,会遍历Bean中的属性,根据类型或名称来完成相应注入,无需额外配置
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
// 深拷贝当前已有的配置
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
// 通过name进行autowired的依赖注入
autowireByName(beanName, mbd, bw, newPvs);
}
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
// 通过type进行autowired的依赖注入
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
// 检查容器是否注册了InstantiationAwareBeanPostProcessor,如果有则执行
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
// 在这执行autowired解析
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
// 进行依赖检查
if (needsDepCheck) {
// 过滤出所有需要进行依赖检查的属性编辑器
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
// 将pvs上所有的属性填充到BeanWrapper对应的Bean实例中
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
解析和注入@Autowired注解方法postProcessProperties
这个方法在AutowiredAnnotationBeanPostProcessor下
重要的组件MergedAnnotations:这个组件是MergedAnnotation的迭代器模式,可以用来解析Class、Field的注解信息
postProcessProperties方法是注入依赖的入口方法
**InjectionMetadata:**这个组件是一个储存InjectedElement的集合,用来储存需要注入的@Autowired的元信息,InjectedElement有两种类型分别是AutowiredFieldElement和AutowiredMethodElement,他们都实现了inject方法,实现了各自的注入方法;
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 解析类的@Autowired注解,将其注解的方法和属性解析成InjectedElement并组合成一个InjectionMetadata
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 调用InjectedElement.inject实现依赖注入
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
@Autowired注解解析方法findAutowiringMetadata
findAutowiringMetadata方法用来获取@Autowired注解的属性的metadata
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// 通过injectionMetadataCache缓存MetaData,key是className
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// 从缓存中获取
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
// 缓存中没有则通过反射获取
metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
通过反射获取@Autowired注解属性
private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
// 处理@Autowired和@Value注解的Field
ReflectionUtils.doWithLocalFields(targetClass, field -> {
// findAutowiredAnnotation方法会遍历属性上的注解,如果有@Autowired或@Value的注解则返回对应的MergedAnnotation
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
// 不可以注入静态的属性
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
// 检查注解的required字段
boolean required = determineRequiredStatus(ann);
// 将这个Field和required组合成一个InjectedElement,并加入currElements List
currElements.add(new AutowiredFieldElement(field, required));
}
});
// 处理@Autowired和@Value注解的Method
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
// 判断方法是否是桥接方法,是的话则需要处理
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
// 获取method上的@Autowired或@Value注解信息
MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
// 不处理静态方法
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static methods: " + method);
}
return;
}
// @Autowired注解应该使用在有参方法上,如果参数数为0会抛出异常
if (method.getParameterCount() == 0) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
// 检查required字段
boolean required = determineRequiredStatus(ann);
// 去寻找getter或setter方法对应的PropertyDescriptor,PropertyDescriptor是描述Java Bean中通过一对存储器方法(getter / setter)导出的一个属性。我们可以通过该PropertyDescriptor对bean中的该属性进行读取和写入操作,也可以设置其getter / setter。
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
// 返回的InjectionMetadata包含@Autowired注解的Field和getter/setter方法
return InjectionMetadata.forElements(elements, clazz);
}
doWithLocalFields主要是通过反射遍历处理类的属性,FieldCallback是一个函数式接口,需要实现dowith方法;
public static void doWithLocalFields(Class<?> clazz, FieldCallback fc) {
for (Field field : getDeclaredFields(clazz)) {
try {
fc.doWith(field);
}
catch (IllegalAccessException ex) {
throw new IllegalStateException("Not allowed to access field '" + field.getName() + "': " + ex);
}
}
}
findAutowiredAnnotation获得Field或Method上的注解信息,如果有@Autowired或@Value注解则返回对应的MergeAnnotation对象
private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
MergedAnnotations annotations = MergedAnnotations.from(ao);
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
MergedAnnotation<?> annotation = annotations.get(type);
// 如果有@Autowired或@Value注解则返回对应的MergeAnnotation对象
if (annotation.isPresent()) {
return annotation;
}
}
return null;
}
doWithLocalMethods主要通过反射遍历处理类的属性,MethodCallback是一个函数式接口,需要实现dowith方法;
public static void doWithLocalMethods(Class<?> clazz, MethodCallback mc) {
Method[] methods = getDeclaredMethods(clazz, false);
for (Method method : methods) {
try {
mc.doWith(method);
}
catch (IllegalAccessException ex) {
throw new IllegalStateException("Not allowed to access method '" + method.getName() + "': " + ex);
}
}
}
findBridgedMethod:处理桥接方法
public static Method findBridgedMethod(Method bridgeMethod) {
if (!bridgeMethod.isBridge()) {
return bridgeMethod;
}
Method bridgedMethod = cache.get(bridgeMethod);
if (bridgedMethod == null) {
// Gather all methods with matching name and parameter size.
List<Method> candidateMethods = new ArrayList<>();
MethodFilter filter = candidateMethod ->
isBridgedCandidateFor(candidateMethod, bridgeMethod);
ReflectionUtils.doWithMethods(bridgeMethod.getDeclaringClass(), candidateMethods::add, filter);
if (!candidateMethods.isEmpty()) {
bridgedMethod = candidateMethods.size() == 1 ?
candidateMethods.get(0) :
searchCandidates(candidateMethods, bridgeMethod);
}
if (bridgedMethod == null) {
// A bridge method was passed in but we couldn't find the bridged method.
// Let's proceed with the passed-in method and hope for the best...
bridgedMethod = bridgeMethod;
}
cache.put(bridgeMethod, bridgedMethod);
}
return bridgedMethod;
}
注入依赖的核心方法inject
获取了类中所有@Autowired字段的metadata后,调用metadata.inject方法进行注入
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
// elementsToIterate集合中就是注解了@Autowired的Field和Method生成的InjectedElement
if (!elementsToIterate.isEmpty()) {
// 执行每一个InjectedElement的inject方法实现依赖注入
for (InjectedElement element : elementsToIterate) {
element.inject(target, beanName, pvs);
}
}
}
Field的注入
Field的注入,执行AutowiredFieldElement.inject
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
// 缓存获取
if (this.cached) {
try {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
value = resolveFieldValue(field, bean, beanName);
}
}
//
else {
value = resolveFieldValue(field, bean, beanName);
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
@Nullable
private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
Object value;
try {
// 通过resolveDependency在容器里寻找bean
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
// 更新缓存
synchronized (this) {
if (!this.cached) {
Object cachedFieldValue = null;
if (value != null || this.required) {
cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
this.cachedFieldValue = cachedFieldValue;
this.cached = true;
}
}
return value;
}
}
Method的注入
Method的注入,执行AutowiredMethodElement.inject
执行流程:
- 首先获取方法执行需要的参数
- 然后反射执行方法
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
if (checkPropertySkipping(pvs)) {
return;
}
Method method = (Method) this.member;
Object[] arguments;
if (this.cached) {
try {
// 通过缓存获取执行方法的参数
arguments = resolveCachedArguments(beanName);
}
catch (NoSuchBeanDefinitionException ex) {
arguments = resolveMethodArguments(method, bean, beanName);
}
}
else {
// 缓存中没有则通过resolveDependency查找依赖参数
arguments = resolveMethodArguments(method, bean, beanName);
}
// 反射执行方法
if (arguments != null) {
try {
ReflectionUtils.makeAccessible(method);
method.invoke(bean, arguments);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
@Nullable
private Object[] resolveMethodArguments(Method method, Object bean, @Nullable String beanName) {
int argumentCount = method.getParameterCount();
Object[] arguments = new Object[argumentCount];
DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount];
Set<String> autowiredBeans = new LinkedHashSet<>(argumentCount);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
for (int i = 0; i < arguments.length; i++) {
MethodParameter methodParam = new MethodParameter(method, i);
DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
currDesc.setContainingClass(bean.getClass());
descriptors[i] = currDesc;
try {
// 依赖参数查找
Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
if (arg == null && !this.required) {
arguments = null;
break;
}
arguments[i] = arg;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
}
}
// 更新缓存
synchronized (this) {
if (!this.cached) {
if (arguments != null) {
DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length);
registerDependentBeans(beanName, autowiredBeans);
if (autowiredBeans.size() == argumentCount) {
Iterator<String> it = autowiredBeans.iterator();
Class<?>[] paramTypes = method.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
String autowiredBeanName = it.next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
descriptors[i], autowiredBeanName, paramTypes[i]);
}
}
}
this.cachedMethodArguments = cachedMethodArguments;
}
else {
this.cachedMethodArguments = null;
}
this.cached = true;
}
}
return arguments;
}
依赖查找核心方法resolveDependency
resolveDependency 是 Spring 进行依赖查找的核心 API,resolveDependency 本质是根据类型查找依赖,调用 beanFactory#beanNamesForType 方法根据类型查找依赖名称。
参数列表:
descriptor:依赖bean的描述器
requestingBeanName:需要注入依赖bean的主bean
autowiredBeanNames:被@Autowired注解的依赖bean names
typeConverter:类型转换器
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
// ParameterNameDiscovery用于解析方法参数名称
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
// 1. Optional<T>
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
// 2. ObjectFactory<T>、ObjectProvider<T>
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
// 3. javax.inject.Provider<T>
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
// 4. @Lazy
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
// 5. 一般情况
if (result == null) {
// 根据类型进行查找
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
一般场景依赖查找方法doResolveDependency:
这个方法会处理四种情况的依赖查找:
- 快速查找:AutowiredAnnotationBeanPostProcessor 处理 @Autowired 注解时,如果注入的对象只有一个,会将该 bean 对应的名称缓存起来,下次直接通过名称查找会快很多
- 注入@Value指定值:QualifierAnnotationAutowireCandidateResolver 处理 @Value 注解时,会读取 @Value 对应的值进行注入。如果是 String 要经过三个过程:①占位符处理 -> ②EL 表达式解析 -> ③类型转换,这也是一般的处理过程,BeanDefinitionValueResolver 处理 String 对象也是这个过程。
- 集合依赖查询:直接全部委托给 resolveMultipleBeans 方法
- 单个依赖查询:调用 findAutowireCandidates 查找所有可用的依赖,如果有多个依赖,则根据规则匹配: @Primary -> @Priority -> ③方法名称或字段名称。findAutowireCandidates只会做查找但是不会对没有初始化的bean做初始化,如果依赖还未初始化,则查到的是依赖的类型,需要调用其他方法进行从初始化;
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
// 1. 快速查找,根据名字查找。AutowiredAnnotationBeanPostProcessor用到
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
// 2. 注入指定值,QualifierAnnotationAutowireCandidateResolver解析@Value会用到
Class<?> type = descriptor.getDependencyType();
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
// 2.1 占位符解析
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
// 2.2 Spring EL 表达式
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
// 2.3 类型转换
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
// 3. 集合依赖,如 Array、List、Set、Map。内部查找依赖也是使用findAutowireCandidates
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// 4. 单个依赖查询
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
// 4.1 没有查找到依赖,判断descriptor.require
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
// 4.2 有多个,需要进行过滤
if (matchingBeans.size() > 1) {
// 4.2.1 @Primary -> @Priority -> 方法名称或字段名称匹配
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
// 4.2.2 根据是否必须,抛出异常。注意这里如果是集合处理,则返回null
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
// 4.3 到这说明依赖已经成功找到并且仅有一个了
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
// 4.4 如果instanceCandidate是一个type类型,说明这个依赖bean尚未实例化,需要调用getBean方法进行实例化
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
findAutowireCandidates
在doResolveDependency方法中,无论是集合依赖还是单一依赖查找,本质上都是调用 findAutowireCandidates 进行类型依赖查找
处理流程主要是三个步骤
- 查找Spring ioc内部依赖,如在 AbstractApplicationContext#prepareBeanFactory 方法中默认设置了如下内部依赖:BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext。
- 根据类型查找beanName,本质上递归调用beanFactory#beanNamesForType,然后进行过滤:
- 使用isSelfReference过滤自身引用
- 检查bd是否允许注入,包含三重规则:①bd.autowireCandidate=true -> ②泛型匹配 -> ③@Qualifier
- 补偿:如果依赖查找没有匹配,则进行补偿:
- 泛型补偿:允许注入对象对象的泛型无法解析
- 自身引用补偿
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
// 1. Spring ioc内部依赖 resolvableDependencies
Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length);
for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
Class<?> autowiringType = classObjectEntry.getKey();
// 1.1 类型匹配
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = classObjectEntry.getValue();
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
// 2. 类型查找:本质上递归调用beanFactory#beanNamesForType。先匹配实例类型,再匹配bd。
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
for (String candidate : candidateNames) {
// 2.1 isSelfReference说明beanName和candidate本质是同一个对象 排除自身引用
// isAutowireCandidate进一步匹配bd.autowireCandidate、泛型、@@Qualifier等进行过滤
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
// 2.2 添加到候选对象中
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// 3. 补偿机制:如果依赖查找无法匹配,怎么办?包含泛型补偿和自身引用补偿两种。
if (result.isEmpty()) {
boolean multiple = indicatesMultipleBeans(requiredType);
// 3.1 fallbackDescriptor: 泛型补偿,实际上是允许注入对象类型的泛型存在无法解析的情况
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
// 3.2 补偿1:不允许自称依赖,但如果是集合依赖,需要过滤非@Qualifier对象。什么场景?
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// 3.3 补偿2:允许自称依赖,但如果是集合依赖,注入的集合依赖中需要过滤自己
if (result.isEmpty() && !multiple) {
for (String candidate : candidateNames) {
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
return result;
}
添加候选bean的方法addCandidateEntry
如果对象还未实例化,Spring 不会画蛇添足将 candidateName 通过 getName 提前实例化。之所以要强调这点,是因为 Spring 的 Bean 生命周期,其实从 Bean 还未实例化就已经开始,Spring 会尽可能的不要初始化该 Bean,除非显式调用 getBean 或不得不实例化时,这点在阅读源码是会感受非常强烈,我们在使用 Spring API 时也要非常注意这点。
private void addCandidateEntry(Map<String, Object> candidates, String candidateName,
DependencyDescriptor descriptor, Class<?> requiredType) {
// 1. 集合依赖,直接调用 getName(candidateName) 实例化
if (descriptor instanceof MultiElementDescriptor) {
// 调用getBean
Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
if (!(beanInstance instanceof NullBean)) {
candidates.put(candidateName, beanInstance);
}
}
// 2. 已经实例化,直接返回实例对象
else if (containsSingleton(candidateName) || (descriptor instanceof StreamDependencyDescriptor &&
((StreamDependencyDescriptor) descriptor).isOrdered())) {
// 调用getBean
Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance));
}
// 3. 只获取candidateName的类型,真正需要注入时才实例化对象
else {
candidates.put(candidateName, getType(candidateName));
}
}
判断对象是否可用的方法
protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd,
DependencyDescriptor descriptor, AutowireCandidateResolver resolver) {
String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
// 1. 传统方式:解析 bd.beanClass,注意 Spring注解驱动时根本不会配置beanClassName
resolveBeanClass(mbd, beanDefinitionName);
// 2. 注解驱动:解析工厂方法 bd.factoryMethodToIntrospect
if (mbd.isFactoryMethodUnique && mbd.factoryMethodToIntrospect == null) {
new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
}
// 3. 直接委托给AutowireCandidateResolver
return resolver.isAutowireCandidate(
new BeanDefinitionHolder(mbd, beanName, getAliases(beanDefinitionName)), descriptor);
}
获取singleton的bean:getSingleton
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
// 首先检查beanName对应的bean实例是否在缓存中存在,如果已经存在,则直接返回
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 缓存中没有,进行bean的创建
if (this.singletonsCurrentlyInDestruction) {
// 当bean工厂的单例处于destruction状态时,不允许进行单例bean创建,抛出异常
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 创建单例前的操作
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 执行singletonFactory的getObject方法获取bean实例
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 后置处理器
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 如果是新的单例对象,将beanName和对应的bean实例添加到缓存中(singletonObjects、registeredSingletons)
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
获得给定bean的实例:getObjectForBeanInstance
getObjectForBeanInstance方法在获得了bean后调用,因为bean有两种:bean、factoryBean;
执行流程:
- 如果是bean类型,直接返回
- 如果是factoryBean类型,则从factoryBean获取对象实例
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// 如果name以“&”为前缀,但是beanInstance不是FactoryBean,则抛异常
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
}
// 如果是bean类型,直接返回本身
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
if (mbd == null) {
// 如果mbd为空,则尝试从factoryBeanObjectCache缓存中获取该FactoryBean创建的对象实例
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// mbd为空,但是该bean的BeanDefinition在缓存中存在,则获取该bean的MergedBeanDefinition
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
// mbd是否是合成的
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 从factoryBean获取对象实例
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
从factoryBean获取对象实例:getObjectFromFactoryBean
- 如果是单例且已经在单例对象缓存中
- 从缓存获取实例
- 如果获取失败,则使用doGetObjectFromFactoryBean方法从factoryBean中获取对象实例
- 如果此时缓存中有了,则替换object
- 如果缓存中没有,则根据条件执行后置处理器,可以通过重写来拓展
- 如果缓存中没有,则使用doGetObjectFromFactoryBean方法从factoryBean中获取对象实例
- 根据条件执行后置处理器
- 返回实例
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// 如果是单例,且已经在单例对象缓存中
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
// 就从缓存中获取对象实例
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
// 如果获取失败 就调用factoryBean的getObject方法获取对象实例
object = doGetObjectFromFactoryBean(factory, beanName);
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
// 如果缓存中没有
if (shouldPostProcess) {
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
// 执行前置处理器 默认只做一些条件判断
beforeSingletonCreation(beanName);
try {
// 执行后置处理器,可以在里面对object做一些处理 默认是没有任何处理
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
//执行后置处理器 默认只做一些条件判断
afterSingletonCreation(beanName);
}
}
// 将生成的实例放入缓存中
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
// 如果缓存中没有
else {
// 从factoryBean中获取对象实例
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
// 执行后置处理器
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
doGetObjectFromFactoryBean方法调用factoryBean的getObject方法获取对象实例
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
// 调用factoryBean的getObject方法获取bean对象实例
try {
//带权限验证的调用方法
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
//不带权限验证的调用方法
else {
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// getObject返回的是空值,并且该FactoryBean正在初始化中,则直接抛异常,不接受一个尚未完全初始化的FactoryBean的getObject返回的空值
if (object == null) {
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
return object;
}
bject;
}
###### 从factoryBean获取对象实例:getObjectFromFactoryBean
1. 如果是单例且已经在单例对象缓存中
1. 从缓存获取实例
2. 如果获取失败,则使用doGetObjectFromFactoryBean方法从factoryBean中获取对象实例
1. 如果此时缓存中有了,则替换object
2. 如果缓存中没有,则根据条件执行后置处理器,可以通过重写来拓展
2. 如果缓存中没有,则使用doGetObjectFromFactoryBean方法从factoryBean中获取对象实例
3. 根据条件执行后置处理器
4. 返回实例
```java
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// 如果是单例,且已经在单例对象缓存中
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
// 就从缓存中获取对象实例
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
// 如果获取失败 就调用factoryBean的getObject方法获取对象实例
object = doGetObjectFromFactoryBean(factory, beanName);
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
// 如果缓存中没有
if (shouldPostProcess) {
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
// 执行前置处理器 默认只做一些条件判断
beforeSingletonCreation(beanName);
try {
// 执行后置处理器,可以在里面对object做一些处理 默认是没有任何处理
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
//执行后置处理器 默认只做一些条件判断
afterSingletonCreation(beanName);
}
}
// 将生成的实例放入缓存中
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
// 如果缓存中没有
else {
// 从factoryBean中获取对象实例
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
// 执行后置处理器
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
doGetObjectFromFactoryBean方法调用factoryBean的getObject方法获取对象实例
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
// 调用factoryBean的getObject方法获取bean对象实例
try {
//带权限验证的调用方法
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
//不带权限验证的调用方法
else {
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// getObject返回的是空值,并且该FactoryBean正在初始化中,则直接抛异常,不接受一个尚未完全初始化的FactoryBean的getObject返回的空值
if (object == null) {
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
return object;
}