项目启动时准备环境
public class SpringApplication {
public ConfigurableApplicationContext run(String... args) {
long startTime = System.nanoTime();
DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
ConfigurableApplicationContext context = null;
this.configureHeadlessProperty();
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 获取环境变量和配置数据
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
this.configureIgnoreBeanInfo(environment);
Banner printedBanner = this.printBanner(environment);
context = this.createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), timeTakenToStartup);
}
listeners.started(context, timeTakenToStartup);
this.callRunners(context, applicationArguments);
} catch (Throwable var12) {
this.handleRunFailure(context, var12, listeners);
throw new IllegalStateException(var12);
}
try {
Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
listeners.ready(context, timeTakenToReady);
return context;
} catch (Throwable var11) {
this.handleRunFailure(context, var11, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var11);
}
}
}
获取系统环境变量和配置数据,加载为Environment
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
ConfigurableEnvironment environment = this.getOrCreateEnvironment();
this.configureEnvironment((ConfigurableEnvironment)environment, applicationArguments.getSourceArgs());
ConfigurationPropertySources.attach((Environment)environment);
listeners.environmentPrepared(bootstrapContext, (ConfigurableEnvironment)environment);
DefaultPropertiesPropertySource.moveToEnd((ConfigurableEnvironment)environment);
Assert.state(!((ConfigurableEnvironment)environment).containsProperty("spring.main.environment-prefix"), "Environment prefix cannot be set via properties.");
this.bindToSpringApplication((ConfigurableEnvironment)environment);
if (!this.isCustomEnvironment) {
environment = this.convertEnvironment((ConfigurableEnvironment)environment);
}
ConfigurationPropertySources.attach((Environment)environment);
return (ConfigurableEnvironment)environment;
}
listeners.environmentPrepared(bootstrapContext, (ConfigurableEnvironment)environment);
public interface PropertySourceLoader {
String[] getFileExtensions();
List> load(String name, Resource resource) throws IOException;
}
spring在5个路径下(classpath/*, classpath/config/*, /*, /config/*, /config/*/*)找application.properties和application.yml配置文件。
注:默认先读取application.properties文件,如果application.properties和application.yml中有相同的属性,那么以application.properties中的值为准,一旦加载到对应的属性,后面就会跳过,不会覆盖前面加载的属性值。
针对application.yml,实现类是YamlPropertySourceLoader
public class YamlPropertySourceLoader implements PropertySourceLoader {
public YamlPropertySourceLoader() {}
public String[] getFileExtensions() {
return new String[]{"yml", "yaml"};
}
public List> load(String name, Resource resource) throws IOException {
if (!ClassUtils.isPresent("org.yaml.snakeyaml.Yaml", this.getClass().getClassLoader())) {
throw new IllegalStateException("Attempted to load " + name + " but snakeyaml was not found on the classpath");
} else {
List
针对application.properties,实现类是PropertiesPropertySourceLoader
public class PropertiesPropertySourceLoader implements PropertySourceLoader {
private static final String XML_FILE_EXTENSION = ".xml";
public PropertiesPropertySourceLoader() {}
public String[] getFileExtensions() {
return new String[]{"properties", "xml"};
}
public List> load(String name, Resource resource) throws IOException {
List
public final class ConfigurationPropertySources {
private static final String ATTACHED_PROPERTY_SOURCE_NAME = "configurationProperties";
public static void attach(Environment environment) {
Assert.isInstanceOf(ConfigurableEnvironment.class, environment);
MutablePropertySources sources = ((ConfigurableEnvironment)environment).getPropertySources();
PropertySource> attached = getAttached(sources);
if (attached == null || !isUsingSources((PropertySource)attached, sources)) {
attached = new ConfigurationPropertySourcesPropertySource("configurationProperties", new SpringConfigurationPropertySources(sources));
}
sources.remove("configurationProperties");
// 将加载了配置文件的PropertySource添加到Environment中
sources.addFirst((PropertySource)attached);
}
}
刷新上下文容器
public class ServletWebServerApplicationContext extends GenericWebApplicationContext implements ConfigurableWebServerApplicationContext {
private void refreshContext(ConfigurableApplicationContext context) {
if (this.registerShutdownHook) {
shutdownHook.registerApplicationContext(context);
}
this.refresh(context);
}
protected void refresh(ConfigurableApplicationContext applicationContext) {
applicationContext.refresh();
}
}
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var10) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
}
this.destroyBeans();
this.cancelRefresh(var10);
throw var10;
} finally {
this.resetCommonCaches();
contextRefresh.end();
}
}
}
}
注册BeanPostProcessors,通过BeanPostProcessor修改bean的属性值
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
}
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
public Object getBean(String name) throws BeansException {
return this.doGetBean(name, (Class)null, (Object[])null, false);
}
protected T doGetBean(String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
}
}
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
this.populateBean(beanName, mbd, instanceWrapper);
}
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
PropertyValues pvsToUse;
for(Iterator var9 = this.getBeanPostProcessorCache().instantiationAware.iterator(); var9.hasNext(); pvs = pvsToUse) {
InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var9.next();
pvsToUse = bp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
}
}
}
通过BeanPostProcessor注入bean的属性
public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
return pvs;
} catch (BeanCreationException var6) {
throw var6;
} catch (Throwable var7) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var7);
}
}
}
public class InjectionMetadata {
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection checkedElements = this.checkedElements;
Collection elementsToIterate = checkedElements != null ? checkedElements : this.injectedElements;
if (!((Collection)elementsToIterate).isEmpty()) {
Iterator var6 = ((Collection)elementsToIterate).iterator();
while(var6.hasNext()) {
InjectionMetadata.InjectedElement element = (InjectionMetadata.InjectedElement)var6.next();
element.inject(target, beanName, pvs);
}
}
}
}
AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(bean, beanName, pvs) -> resolveFieldValue(field, bean, beanName) ->
bean属性注入
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 = AutowiredAnnotationBeanPostProcessor.this.resolvedCachedArgument(beanName, this.cachedFieldValue);
} catch (NoSuchBeanDefinitionException var7) {
value = this.resolveFieldValue(field, bean, beanName);
}
} else {
// 获取字段@Value对应的值
value = this.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 autowiredBeanNames = new LinkedHashSet(1);
Assert.state(AutowiredAnnotationBeanPostProcessor.this.beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = AutowiredAnnotationBeanPostProcessor.this.beanFactory.getTypeConverter();
Object value;
try {
// 获取字段依赖的属性值
value = AutowiredAnnotationBeanPostProcessor.this.beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
} catch (BeansException var12) {
throw new UnsatisfiedDependencyException((String)null, beanName, new InjectionPoint(field), var12);
}
synchronized(this) {
if (!this.cached) {
Object cachedFieldValue = null;
if (value != null || this.required) {
cachedFieldValue = desc;
AutowiredAnnotationBeanPostProcessor.this.registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = (String)autowiredBeanNames.iterator().next();
if (AutowiredAnnotationBeanPostProcessor.this.beanFactory.containsBean(autowiredBeanName) && AutowiredAnnotationBeanPostProcessor.this.beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
cachedFieldValue = new AutowiredAnnotationBeanPostProcessor.ShortcutDependencyDescriptor(desc, autowiredBeanName, field.getType());
}
}
}
this.cachedFieldValue = cachedFieldValue;
this.cached = true;
}
return value;
}
}
获取注入依赖
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName, @Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(this.getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {
return this.createOptionalDependency(descriptor, requestingBeanName);
} else if (ObjectFactory.class != descriptor.getDependencyType() && ObjectProvider.class != descriptor.getDependencyType()) {
if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return (new DefaultListableBeanFactory.Jsr330Factory()).createDependencyProvider(descriptor, requestingBeanName);
} else {
Object result = this.getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);
if (result == null) {
result = this.doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
} else {
return new DefaultListableBeanFactory.DependencyObjectProvider(descriptor, requestingBeanName);
}
}
}
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
Object var23;
try {
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
Object var20 = shortcut;
return var20;
}
Class> type = descriptor.getDependencyType();
Object value = this.getAutowireCandidateResolver().getSuggestedValue(descriptor);
Object var11;
if (value == null) {
Object multipleBeans = this.resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
var23 = multipleBeans;
return var23;
}
Map matchingBeans = this.findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (this.isRequired(descriptor)) {
this.raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
var11 = null;
return var11;
}
Object instanceCandidate;
Object result;
String autowiredBeanName;
if (matchingBeans.size() > 1) {
autowiredBeanName = this.determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (!this.isRequired(descriptor) && this.indicatesMultipleBeans(type)) {
result = null;
return result;
}
result = descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
return result;
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
} else {
Entry entry = (Entry)matchingBeans.entrySet().iterator().next();
autowiredBeanName = (String)entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
result = instanceCandidate;
if (instanceCandidate instanceof NullBean) {
if (this.isRequired(descriptor)) {
this.raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
Object var14 = result;
return var14;
}
if (value instanceof String) {
// 获取bean注入的属性值
String strVal = this.resolveEmbeddedValue((String)value);
BeanDefinition bd = beanName != null && this.containsBean(beanName) ? this.getMergedBeanDefinition(beanName) : null;
value = this.evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = typeConverter != null ? typeConverter : this.getTypeConverter();
try {
var23 = converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
} catch (UnsupportedOperationException var18) {
var11 = descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter());
return var11;
}
} finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
return var23;
}
AbstractBeanFactory.resolveEmbeddedValue(value)
根据@Value注解的key获取对应的值
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
@Nullable
public String resolveEmbeddedValue(@Nullable String value) {
if (value == null) {
return null;
} else {
String result = value;
Iterator var3 = this.embeddedValueResolvers.iterator();
do {
if (!var3.hasNext()) {
return result;
}
StringValueResolver resolver = (StringValueResolver)var3.next();
result = resolver.resolveStringValue(result);
} while(result != null);
return null;
}
}
}
最后通过反射给目标字段赋值
public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
private class AutowiredFieldElement extends InjectedElement {
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 = AutowiredAnnotationBeanPostProcessor.this.resolvedCachedArgument(beanName, this.cachedFieldValue);
} catch (NoSuchBeanDefinitionException var7) {
value = this.resolveFieldValue(field, bean, beanName);
}
} else {
// 获取字段@Value对应的值
value = this.resolveFieldValue(field, bean, beanName);
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
// 通过反射给目标字段赋值
field.set(bean, value);
}
}
}
}
field.set(bean, value);
public final class Field extends AccessibleObject implements Member {
@CallerSensitive
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).set(obj, value);
}
}