不要问我阅读spring源码有什么用,问就是没有用,只是让我自己使用spring的过程中自信点!
相关文章
过程
1. @ConfigurationProperties 绑定数据是通过ben的后置处理器实现的
2. bean后置处理器是 ConfigurationPropertiesBindingPostProcessor
3. 流程为 ioc容器初始化 -> 创建目标bean -> 执行initializeBean -> 执行后置处理器 -> 对字段赋值
//这块代码段 是 ioc 容器初始化的 一部分 不清楚的可以看下以前的文章
//populateBean() 处理以来注入
//initializeBean() 后置处理器的一些处理 还有一些初始化的处理
//例如 加入bean 实现了 InitializingBean 接口 执行其 afterPropertiesSet() 方法 之类...
Object exposedObject = bean;
try {
//这个依赖注入的不看了 以后会单独讲
populateBean(beanName, mbd, instanceWrapper);
//本文的重点
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//假如bean 实现了 BeanNameAware,BeanClassLoaderAware,BeanFactoryAware接口 执行他们的实现方法
//其实这个地方就可以当做一个bean的初始化的处理
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//主线
//执行后置处理器 Before
// 数据绑定是 执行的 postProcessBeforeInitialization
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//假如实现了InitializingBean 执行afterPropertiesSet()方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//执行后置处理器 After
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//循坏 执行后置处理器
//我们 关注 ConfigurationPropertiesBindingPostProcessor
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
ConfigurationPropertiesBindingPostProcessor
//当前代码位置 ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization()
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//先看下ConfigurationPropertiesBean.get() 方法
bind(ConfigurationPropertiesBean.get(this.applicationContext, bean, beanName));
return bean;
}
//
public static ConfigurationPropertiesBean get(ApplicationContext applicationContext, Object bean, String beanName) {
//查询工厂方法,就是看看是不是@bean 创建的
Method factoryMethod = findFactoryMethod(applicationContext, beanName);
//创建ConfigurationPropertiesBean
//// 主要看下这个方法
return create(beanName, bean, bean.getClass(), factoryMethod);
}
private static ConfigurationPropertiesBean create(String name, Object instance, Class<?> type, Method factory) {
// 看这里,主要为了这句话
// 判断当前bean 上面是否存在 @ConfigurationProperties 注解
ConfigurationProperties annotation = findAnnotation(instance, type, factory, ConfigurationProperties.class);
// 假如为空,直接返回 null
//这个地方就是说,虽然每个类都会走这个后置处理器,但是没有 @ConfigurationProperties 的话,到这里就结束了
if (annotation == null) {
return null;
}
Validated validated = findAnnotation(instance, type, factory, Validated.class);
Annotation[] annotations = (validated != null) ? new Annotation[] { annotation, validated }
: new Annotation[] { annotation };
ResolvableType bindType = (factory != null) ? ResolvableType.forMethodReturnType(factory)
: ResolvableType.forClass(type);
Bindable<Object> bindTarget = Bindable.of(bindType).withAnnotations(annotations);
if (instance != null) {
bindTarget = bindTarget.withExistingValue(instance);
}
return new ConfigurationPropertiesBean(name, instance, annotation, bindTarget);
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//然后看下bind() 方法
bind(ConfigurationPropertiesBean.get(this.applicationContext, bean, beanName));
return bean;
}
private void bind(ConfigurationPropertiesBean bean) {
// 假如 bean 为 null 直接结束了
if (bean == null || hasBoundValueObject(bean.getName())) {
return;
}
Assert.state(bean.getBindMethod() == BindMethod.JAVA_BEAN, "Cannot bind @ConfigurationProperties for bean '"
+ bean.getName() + "'. Ensure that @ConstructorBinding has not been applied to regular bean");
try {
//this.binder 是实际处理绑定的 处理类,后面会讲实在什么地方创建的
this.binder.bind(bean);
}
catch (Exception ex) {
throw new ConfigurationPropertiesBindException(bean, ex);
}
}
ConfigurationPropertiesBinder
BindResult<?> bind(ConfigurationPropertiesBean propertiesBean) {
//获取目标类
Bindable<?> target = propertiesBean.asBindTarget();
//获取注解
ConfigurationProperties annotation = propertiesBean.getAnnotation();
BindHandler bindHandler = getBindHandler(target, annotation);
//获取注解的 参数 也就是 ConfigurationProperties 配置的前缀
//getBinder() 就是获取 Binder , binder 的创建后面会讲
return getBinder().bind(annotation.prefix(), target, bindHandler);
}
Binder
ConfigurationPropertiesBinder 绑定的处理 是委托给 Binder处理的
public <T> BindResult<T> bind(String name, Bindable<T> target, BindHandler handler) {
//注意这个 name 为 前缀,就是你配置的 值
return bind(ConfigurationPropertyName.of(name), target, handler);
}
public <T> BindResult<T> bind(ConfigurationPropertyName name, Bindable<T> target, BindHandler handler) {
//这里 , 只是一个透传
T bound = bind(name, target, handler, false);
return BindResult.of(bound);
}
private <T> T bind(ConfigurationPropertyName name, Bindable<T> target, BindHandler handler, boolean create) {
Assert.notNull(name, "Name must not be null");
Assert.notNull(target, "Target must not be null");
handler = (handler != null) ? handler : this.defaultBindHandler;
Context context = new Context();
return bind(name, target, handler, context, false, create);
}
private <T> T bind(ConfigurationPropertyName name, Bindable<T> target, BindHandler handler, Context context,
boolean allowRecursiveBinding, boolean create) {
try {
Bindable<T> replacementTarget = handler.onStart(name, target, context);
if (replacementTarget == null) {
return handleBindResult(name, target, handler, context, null, create);
}
target = replacementTarget;
Object bound = bindObject(name, target, handler, context, allowRecursiveBinding);
return handleBindResult(name, target, handler, context, bound, create);
}
catch (Exception ex) {
return handleBindError(name, target, handler, context, ex);
}
}
private <T> Object bindObject(ConfigurationPropertyName name, Bindable<T> target, BindHandler handler,
Context context, boolean allowRecursiveBinding) {
//这个方法很重要 就是在这里实现了绑定,等下回回过头讲,这是第一次 记住现在的 name 是 配置的前缀,不会得到值
ConfigurationProperty property = findProperty(name, context);
if (property == null && context.depth != 0 && containsNoDescendantOf(context.getSources(), name)) {
return null;
}
AggregateBinder<?> aggregateBinder = getAggregateBinder(target, context);
if (aggregateBinder != null) {
return bindAggregate(name, target, handler, context, aggregateBinder);
}
if (property != null) {
try {
return bindProperty(target, context, property);
}
catch (ConverterNotFoundException ex) {
// We might still be able to bind it using the recursive binders
Object instance = bindDataObject(name, target, handler, context, allowRecursiveBinding);
if (instance != null) {
return instance;
}
throw ex;
}
}
//这里
return bindDataObject(name, target, handler, context, allowRecursiveBinding);
}
//这个方法很重要,也相当的绕,多次使用了 函数式编程,,, 必须对 java8 的函数式编程熟悉才能搞明白
private Object bindDataObject(ConfigurationPropertyName name, Bindable<?> target, BindHandler handler,
Context context, boolean allowRecursiveBinding) {
if (isUnbindableBean(name, target, context)) {
return null;
}
//获取目标类型
Class<?> type = target.getType().resolve(Object.class);
// 判断是否已经在绑定了 , 绑定的都会记录到 dataObjectBindings
if (!allowRecursiveBinding && context.isBindingDataObject(type)) {
return null;
}
//这里 创建了一个 行为函数 (函数式接口) , 注意,这个是否当前的函数还没有执行
//他有两个参数
DataObjectPropertyBinder propertyBinder = (propertyName, propertyTarget) -> bind(name.append(propertyName),
propertyTarget, handler, context, false, false);
//这里 context.withDataObject 方法 有两个参数 1. 目标类 2.函数式接口
//普及下知识: 函数式接口 可以用 接口,lambda,方法引用表示,这里使用的是lambada ,上面的也是
// withDataObject 方法 东西比较式少就不看了,这个 函数式接口是 Supplier 只有一个 T get() 方法
//意味着,不接受参数 有一个返回值
//withDataObject 放当前目标类型 存入 dataObjectBindings 中,然后 执行 函数式接口 的 get 方法
return context.withDataObject(type, () -> {
//然后执行到了这里
//获取到 Binder 的 dataObjectBinders属性 , 里面包含两个实例,
//分别为 JavaBeanBinder , ValueObjectBinder,从名字可以看出,一个处理baen,和value
//this.dataObjectBinders 是在 创建 Binder 的时候创建的,后面会讲
for (DataObjectBinder dataObjectBinder : this.dataObjectBinders) {
// 然后委托给 dataObjectBinder,我们是处理 bean 所以直接看 JavaBeanBinder,ValueObjectBinder注定得不到结果
//注意下传参,propertyBinder 为上述提到的 函数式接口,当一个参数传递进去
//看下 JavaBeanBinder.bind()
Object instance = dataObjectBinder.bind(name, target, context, propertyBinder);
if (instance != null) {
return instance;
}
}
return null;
});
}
@Override
public <T> T bind(ConfigurationPropertyName name, Bindable<T> target, Context context,
DataObjectPropertyBinder propertyBinder) {
//注意 当前 name 还只是 前缀
boolean hasKnownBindableProperties = target.getValue() != null && hasKnownBindableProperties(name, context);
//这个方法很重要,我们先看下
Bean<T> bean = Bean.get(target, hasKnownBindableProperties);
if (bean == null) {
return null;
}
BeanSupplier<T> beanSupplier = bean.getSupplier(target);
boolean bound = bind(propertyBinder, bean, beanSupplier, context);
return (bound ? beanSupplier.get() : null);
}
//Bean 的 属性有 : cached type resolvedType properties
static <T> Bean<T> get(Bindable<T> bindable, boolean canCallGetValue) {
ResolvableType type = bindable.getType();
Class<?> resolvedType = type.resolve(Object.class);
Supplier<T> value = bindable.getValue();
T instance = null;
if (canCallGetValue && value != null) {
instance = value.get();
resolvedType = (instance != null) ? instance.getClass() : resolvedType;
}
if (instance == null && !isInstantiable(resolvedType)) {
return null;
}
Bean<?> bean = Bean.cached;
if (bean == null || !bean.isOfType(type, resolvedType)) {
//主要看下这个构造方法
bean = new Bean<>(type, resolvedType);
cached = bean;
}
return (Bean<T>) bean;
}
Bean(ResolvableType type, Class<?> resolvedType) {
//对属性分别赋值
this.type = type;
this.resolvedType = resolvedType;
//这里
addProperties(resolvedType);
}
private void addProperties(Class<?> type) {
//目标类型不为 null 不为 Object , 我们当前是满足这个条件的
while (type != null && !Object.class.equals(type)) {
//获取目标类的所有方法
Method[] declaredMethods = type.getDeclaredMethods();
//获取目标类的所有属性
Field[] declaredFields = type.getDeclaredFields();
//这里 传入参数 所有方法和属性
addProperties(declaredMethods, declaredFields);
type = type.getSuperclass();
}
}
protected void addProperties(Method[] declaredMethods, Field[] declaredFields) {
for (int i = 0; i < declaredMethods.length; i++) {
//循环所有的方法,判断是否满足添加
//条件为 修饰符 不能是 Private, Protected,不能是抽象方法,不能是静态方法,类不能是Object,方法名不能是$开头
if (!isCandidate(declaredMethods[i])) {
//假如上述条件有一个不满足 就清除掉这个方法
declaredMethods[i] = null;
}
}
//循环符合条件的方法
for (Method method : declaredMethods) {
//看下 这个发放干了啥
//获取所有的 get方法
addMethodIfPossible(method, "get", 0, BeanProperty::addGetter);
addMethodIfPossible(method, "is", 0, BeanProperty::addGetter);
}
for (Method method : declaredMethods) {
//获取所有的set方法
addMethodIfPossible(method, "set", 1, BeanProperty::addSetter);
}
//处理类
for (Field field : declaredFields) {
// 放入 properties 属性的中
//Map<String, BeanProperty> properties
//键值对的key为 属性名, BeanProperty 中包含了 这个属性的 get set 方法
addField(field);
}
}
private void addMethodIfPossible(Method method, String prefix, int parameterCount,
BiConsumer<BeanProperty, Method> consumer) {
//方法名要包含 出入的 前缀,并且长度大于他 就是说,这是是判断是不是 get set is 方法
if (method != null && method.getParameterCount() == parameterCount && method.getName().startsWith(prefix)
&& method.getName().length() > prefix.length()) {
//假如是
//感觉方法名 截取 方法前缀 获取属性名
String propertyName = Introspector.decapitalize(method.getName().substring(prefix.length()));
//设置 get set 方法 这个地方 consumer 是方法引用 是不同的方法
consumer.accept(this.properties.computeIfAbsent(propertyName, this::getBeanProperty), method);
}
}
//到这里获取到了 Bean 这个类,包含了这个目标类的 所有字段名称和 get set 方法
//继续看主线
@Override
public <T> T bind(ConfigurationPropertyName name, Bindable<T> target, Context context,
DataObjectPropertyBinder propertyBinder) {
boolean hasKnownBindableProperties = target.getValue() != null && hasKnownBindableProperties(name, context);
// Bean.get() 方法上面已经看过
Bean<T> bean = Bean.get(target, hasKnownBindableProperties);
if (bean == null) {
return null;
}
//这个只是获取了一个函数式接口,还没执行
BeanSupplier<T> beanSupplier = bean.getSupplier(target);
//这里 , propertyBinder beanSupplier 函数式接口
boolean bound = bind(propertyBinder, bean, beanSupplier, context);
return (bound ? beanSupplier.get() : null);
}
private <T> boolean bind(DataObjectPropertyBinder propertyBinder, Bean<T> bean, BeanSupplier<T> beanSupplier,
Context context) {
boolean bound = false;
//循环说有的类 , 应该还记得 beanProperty 就是一个 类的封装信息,包含属性名,get set 方法
for (BeanProperty beanProperty : bean.getProperties().values()) {
//这里
bound |= bind(beanSupplier, propertyBinder, beanProperty);
context.clearConfigurationProperty();
}
return bound;
}
private <T> boolean bind(BeanSupplier<T> beanSupplier, DataObjectPropertyBinder propertyBinder,
BeanProperty property) {
// 属性名
String propertyName = property.getName();
// 属性类型
ResolvableType type = property.getType();
Supplier<Object> value = property.getValue(beanSupplier);
// 属性注解
Annotation[] annotations = property.getAnnotations();
//调用了 propertyBinder 函数式接口 , 传递了这么远,终于要执行了
//传递了 类型 和 Bindable
Object bound = propertyBinder.bindProperty(propertyName,
Bindable.of(type).withSuppliedValue(value).withAnnotations(annotations));
if (bound == null) {
return false;
}
//这个 获取到 这个属性的 值,假如存在 set 方法, 将其值放入 value 中
//也就是说,假如没有set 方法 是没有办法赋值的
if (property.isSettable()) {
property.setValue(beanSupplier, bound);
}
else if (value == null || !bound.equals(value.get())) {
throw new IllegalStateException("No setter found for property: " + property.getName());
}
return true;
}
//还记得这句代码吧
//结合上面的方法 name 为前缀,propertyName为列名, 拼一起是 配置名称
DataObjectPropertyBinder propertyBinder = (propertyName, propertyTarget) -> bind(name.append(propertyName),
propertyTarget, handler, context, false, false);
//又来到了这个方法,上次的 name 是前缀,这次是 配置名称
private <T> T bind(ConfigurationPropertyName name, Bindable<T> target, BindHandler handler, Context context,
boolean allowRecursiveBinding, boolean create) {
try {
Bindable<T> replacementTarget = handler.onStart(name, target, context);
if (replacementTarget == null) {
return handleBindResult(name, target, handler, context, null, create);
}
target = replacementTarget;
//这里
Object bound = bindObject(name, target, handler, context, allowRecursiveBinding);
return handleBindResult(name, target, handler, context, bound, create);
}
catch (Exception ex) {
return handleBindError(name, target, handler, context, ex);
}
}
private <T> Object bindObject(ConfigurationPropertyName name, Bindable<T> target, BindHandler handler,
Context context, boolean allowRecursiveBinding) {
//这个方法 上面提到过 会讲,重点 先看下
ConfigurationProperty property = findProperty(name, context);
if (property == null && context.depth != 0 && containsNoDescendantOf(context.getSources(), name)) {
return null;
}
AggregateBinder<?> aggregateBinder = getAggregateBinder(target, context);
if (aggregateBinder != null) {
return bindAggregate(name, target, handler, context, aggregateBinder);
}
if (property != null) {
try {
return bindProperty(target, context, property);
}
catch (ConverterNotFoundException ex) {
// We might still be able to bind it using the recursive binders
Object instance = bindDataObject(name, target, handler, context, allowRecursiveBinding);
if (instance != null) {
return instance;
}
throw ex;
}
}
return bindDataObject(name, target, handler, context, allowRecursiveBinding);
}
private ConfigurationProperty findProperty(ConfigurationPropertyName name, Context context) {
if (name.isEmpty()) {
return null;
}
// context.getSources() Binder 中的 sources 属性
//实现类为 SpringConfigurationPropertySources 实现了 Iterable 接口,意味着 这个类可以遍历
//所以不要奇怪这个属性为啥可以 for
//这里想看下 SpringConfigurationPropertySources 的 iterator 方法 返回的啥吧,要不然也是懵逼的,
// iterator 方法返回的就是 next() 方法的返回 就是 for 每次的值
for (ConfigurationPropertySource source : context.getSources()) {
ConfigurationProperty property = source.getConfigurationProperty(name);
if (property != null) {
return property;
}
}
return null;
}
//位置 org.springframework.boot.context.properties.source.SpringConfigurationPropertySources.iterator()
@Override
public Iterator<ConfigurationPropertySource> iterator() {
//好吧,发现实际是调用其属性 sources 的 iterator()
//this::adapt 要注意下, 后面会发现是使用 MutablePropertySources.
//但是MutablePropertySources.propertySourceList只有两个元素,
//就是因为 this::adapt 才能那种所有的 数据源
//内容很多,不看了,大概知道这个意思就行
return new SourcesIterator(this.sources.iterator(), this::adapt);
}
//位置 org.springframework.core.env.MutablePropertySources.iterator()
@Override
public Iterator<PropertySource<?>> iterator() {
//发现最后使用的 是 其属性 propertySourceList
//记住了 那个 for 循环实际上是循环的 propertySourceList 这个集合
return this.propertySourceList.iterator();
}
private ConfigurationProperty findProperty(ConfigurationPropertyName name, Context context) {
if (name.isEmpty()) {
return null;
}
// context.getSources() Binder 中的 sources 属性
//实现类为 SpringConfigurationPropertySources 实现了 Iterable 接口,意味着 这个类可以遍历
//所以不要奇怪这个属性为啥可以 for
//这里想看下 SpringConfigurationPropertySources 的 iterator 方法 返回的啥吧,要不然也是懵逼的,
// iterator 方法返回的就是 next() 方法的返回 就是 for 每次的值
for (ConfigurationPropertySource source : context.getSources()) {
//获取值
//循环着所有的配置文件,直到找到值结束
//所以说赋值的过程结束了,我们现在要看看 数据源的来源
ConfigurationProperty property = source.getConfigurationProperty(name);
if (property != null) {
return property;
}
}
return null;
}
数据来源
1. 上面已经知道数据源实在 org.springframework.core.env.MutablePropertySources.propertySourceList 中保存的
2. 注意,下面的代码 , 很多都是倒叙的
//看下数据来源
//MutablePropertySources 是 SpringConfigurationPropertySources.sources属性
//代码如下
SpringConfigurationPropertySources(Iterable<PropertySource<?>> sources) {
Assert.notNull(sources, "Sources must not be null");
this.sources = sources;
}
//现在知道了MutablePropertySources 是在 SpringConfigurationPropertySources() 构造方法中赋值的,那就看看什么什么调用的这个方法
//代码如下:
//这个方法 是在 处理数据绑定的时候调用的,上面不是提到过吗,数据绑定是委托给ConfigurationPropertiesBinder 这个类处理的
//当前位置 ConfigurationPropertiesBinder
private Binder getBinder() {
if (this.binder == null) {
//主要看下第一个参数,就是 SpringConfigurationPropertySources
//所以我们要看下 getConfigurationPropertySources(),是日如何拿到数据的
this.binder = new Binder(getConfigurationPropertySources(), getPropertySourcesPlaceholdersResolver(),
getConversionService(), getPropertyEditorInitializer(), null,
ConfigurationPropertiesBindConstructorProvider.INSTANCE);
}
return this.binder;
}
//当前位置 ConfigurationPropertiesBinder
private Iterable<ConfigurationPropertySource> getConfigurationPropertySources() {
return ConfigurationPropertySources.from(this.propertySources);
}
//当前位置 ConfigurationPropertiesBinder
public static Iterable<ConfigurationPropertySource> from(Iterable<PropertySource<?>> sources) {
//这个传入的参数就是 MutablePropertySources
//最后发现 MutablePropertySources 竟然是 ConfigurationPropertiesBinder 的 propertySources 属性
return new SpringConfigurationPropertySources(sources);
}
//接下来我们要看下 ConfigurationPropertiesBinder.propertySources 属性是在什么地方被赋值的
//当前位置 ConfigurationPropertiesBinder
ConfigurationPropertiesBinder(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
//发现是在这个地方赋值的
//那就看下 getPropertySources() 干了啥
//注意,PropertySourcesDeducer() 构造方法,传递了 applicationContext
this.propertySources = new PropertySourcesDeducer(applicationContext).getPropertySources();
this.configurationPropertiesValidator = getConfigurationPropertiesValidator(applicationContext);
this.jsr303Present = ConfigurationPropertiesJsr303Validator.isJsr303Present(applicationContext);
}
//当前位置 org.springframework.boot.context.properties.PropertySourcesDeducer.getPropertySources()
PropertySources getPropertySources() {
//数据来源
//PropertySourcesPlaceholderConfigurer 是个 bean工厂 的后置处理器
PropertySourcesPlaceholderConfigurer configurer = getSinglePropertySourcesPlaceholderConfigurer();
if (configurer != null) {
// 发现响应的数据是从configurer来的
return configurer.getAppliedPropertySources();
}
MutablePropertySources sources = extractEnvironmentPropertySources();
Assert.state(sources != null,
"Unable to obtain PropertySources from PropertySourcesPlaceholderConfigurer or Environment");
return sources;
}
//当前位置 PropertySourcesDeducer.getSinglePropertySourcesPlaceholderConfigurer()
//这个方法 就是获取 PropertySourcesPlaceholderConfigurer 这个 bean工厂后置处理器
private PropertySourcesPlaceholderConfigurer getSinglePropertySourcesPlaceholderConfigurer() {
// Take care not to cause early instantiation of all FactoryBeans
Map<String, PropertySourcesPlaceholderConfigurer> beans = this.applicationContext
.getBeansOfType(PropertySourcesPlaceholderConfigurer.class, false, false);
if (beans.size() == 1) {
return beans.values().iterator().next();
}
if (beans.size() > 1 && logger.isWarnEnabled()) {
logger.warn("Multiple PropertySourcesPlaceholderConfigurer beans registered " + beans.keySet()
+ ", falling back to Environment");
}
return null;
}
//到目前位置 我们应该知道了,数据的来源是在:
//bean工厂后置处理器 PropertySourcesPlaceholderConfigurer.appliedPropertySources 属性.
//接下来就看看这个数据 是什么时候被添加进去的.
//当前位置 PropertySourcesPlaceholderConfigurer.postProcessBeanFactory(ConfigurableListableBeanFactory)
//postProcessBeanFactory 方法是 bean工厂后置处理器的顶层接口的方法
//假如对 bean工厂后置处理器不明白 可以去看以前的文章
//当前方法 :
//PropertySourcesPlaceholderConfigurer 在 执行的时候 执行了当前方法,是在 AbstractApplicationContext.refresh()中执行的
//但是 数据源是在 environment 中保存的,现在就要看下 environment 是在什么时候赋值的
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
//environment 是 ioc 容器的属性
if (this.propertySources == null) {
this.propertySources = new MutablePropertySources();
if (this.environment != null) {
//这里
this.propertySources.addLast(
new PropertySource<Environment>(ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME, this.environment) {
@Override
@Nullable
public String getProperty(String key) {
return this.source.getProperty(key);
}
}
);
}
try {
PropertySource<?> localPropertySource =
new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, mergeProperties());
if (this.localOverride) {
this.propertySources.addFirst(localPropertySource);
}
else {
this.propertySources.addLast(localPropertySource);
}
}
catch (IOException ex) {
throw new BeanInitializationException("Could not load properties", ex);
}
}
processProperties(beanFactory, new PropertySourcesPropertyResolver(this.propertySources));
//发现 属性是在这里赋值的
this.appliedPropertySources = this.propertySources;
}
//这个方法 是在 一个bean ioc初始化完成的时候.执行的,具体位置在:
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(String, Object, RootBeanDefinition)
private void invokeAwareInterfaces(Object bean) {
//当前bean工厂后置处理器 实现了 EnvironmentAware接口
if (bean instanceof EnvironmentAware) {
//这里给这个类赋值了 ioc 容器的环境 Environment
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
//总结就是 数据源是在 applicationContext.environment中保存的,接下来就要看看 applicationContext.environment是怎么来的
//applicationContext.environment
//当前位置 org.springframework.boot.SpringApplication.run(String...)
//这个方法就是 springboot 的启动入口
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//本文主要关注这行代码
//直接翻译,准备 环境
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
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);
}
...................................
return context;
}
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments) {
// Create and configure the environment
//这里是记载一些系统的配置文件
ConfigurableEnvironment environment = getOrCreateEnvironment();
configureEnvironment(environment, applicationArguments.getSourceArgs());
ConfigurationPropertySources.attach(environment);
//这里 大概看的出是要执行监听器
listeners.environmentPrepared(environment);
bindToSpringApplication(environment);
if (!this.isCustomEnvironment) {
environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
deduceEnvironmentClass());
}
ConfigurationPropertySources.attach(environment);
return environment;
}
@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
//这里发布了一个 ApplicationEnvironmentPreparedEvent 事件
this.initialMulticaster
.multicastEvent(new ApplicationEnvironmentPreparedEvent(this.application, this.args, environment));
}
//接下来就是spring 监听器的 源码了 大致看下
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
//这里的getApplicationListeners方法是获取 监听了当前事件 的监听器
//具体只能获取的就不看了,大致就是 你添加的监听器的生活,spring 会以 key(事件) - list<监听器> 这种来存储
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
//循环执行 监听器
invokeListener(listener, event);
}
}
}
@SuppressWarnings({"rawtypes", "unchecked"})
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
//执行监听器的 onApplicationEvent 方法
// 我们需要关注的监听器是 ConfigFileApplicationListener
listener.onApplicationEvent(event);
}
catch (ClassCastException ex) {
String msg = ex.getMessage();
if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
// Possibly a lambda-defined listener which we could not resolve the generic event type for
// -> let's suppress the exception and just log a debug message.
Log logger = LogFactory.getLog(getClass());
if (logger.isTraceEnabled()) {
logger.trace("Non-matching event type for listener: " + listener, ex);
}
}
else {
throw ex;
}
}
}
//当前位置 ConfigFileApplicationListener.onApplicationEvent(ApplicationEvent)
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationEnvironmentPreparedEvent) {
//这里
onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
}
if (event instanceof ApplicationPreparedEvent) {
onApplicationPreparedEvent(event);
}
}
private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {
List<EnvironmentPostProcessor> postProcessors = loadPostProcessors();
postProcessors.add(this);
AnnotationAwareOrderComparator.sort(postProcessors);
for (EnvironmentPostProcessor postProcessor : postProcessors) {
//这里循环一些处理器.
//当前类也是处理器
//主要就是看当前类的 postProcessEnvironment
postProcessor.postProcessEnvironment(event.getEnvironment(), event.getSpringApplication());
}
}
//
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
addPropertySources(environment, application.getResourceLoader());
}
protected void addPropertySources(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {
RandomValuePropertySource.addToEnvironment(environment);
// 看下 这行代码
new Loader(environment, resourceLoader).load();
}
//当前位置 : org.springframework.boot.context.config.ConfigFileApplicationListener.Loader.load()
void load() {
FilteredPropertySource.apply(this.environment, DEFAULT_PROPERTIES, LOAD_FILTERED_PROPERTY,
(defaultProperties) -> {
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 (isDefaultProfile(profile)) {
addProfileToEnvironment(profile.getName());
}
//这里
load(profile, this::getPositiveProfileFilter,
addToLoaded(MutablePropertySources::addLast, false));
this.processedProfiles.add(profile);
}
load(null, this::getNegativeProfileFilter, addToLoaded(MutablePropertySources::addFirst, true));
addLoadedPropertySources();
applyActiveProfiles(defaultProperties);
});
}
private void load(Profile profile, DocumentFilterFactory filterFactory, DocumentConsumer consumer) {
// getSearchLocations 获取的是从哪些路径下加载配置文件
// [file:./config/, file:./config/*/, file:./, classpath:/config/, classpath:/]
getSearchLocations().forEach((location) -> {
boolean isDirectory = location.endsWith("/");
//获取
Set<String> names = isDirectory ? getSearchNames() : NO_SEARCH_NAMES;
names.forEach((name) -> load(location, name, profile, filterFactory, consumer));
});
}
private void load(String location, String name, Profile profile, DocumentFilterFactory filterFactory,
DocumentConsumer consumer) {
if (!StringUtils.hasText(name)) {
//this.propertySourceLoaders 是对不同文件的处理器 propertise yml
for (PropertySourceLoader loader : this.propertySourceLoaders) {
if (canLoadFileExtension(loader, location)) {
//这里
load(loader, location, profile, filterFactory.getDocumentFilter(profile), consumer);
return;
}
}
throw new IllegalStateException("File extension of config file location '" + location
+ "' is not known to any PropertySourceLoader. If the location is meant to reference "
+ "a directory, it must end in '/'");
}
Set<String> processed = new HashSet<>();
for (PropertySourceLoader loader : this.propertySourceLoaders) {
for (String fileExtension : loader.getFileExtensions()) {
if (processed.add(fileExtension)) {
loadForFileExtension(loader, location + name, "." + fileExtension, profile, filterFactory,
consumer);
}
}
}
}
//结束