SpringFactoriesLoader
示例位置 SpringApplication#getSpringFactoriesInstances
加载spring.factroies下的初始化类
ClassLoader classLoader = this.getClassLoader();
Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
说明:
SpringFactoriesLoader.loadFactoryNames 加载type为spring.factroies 下的 class的key值
List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader)
ClassUtils .BeanUtils
示例位置 SpringApplication#createSpringFactoriesInstances
try {
Class<?> instanceClass = ClassUtils.forName(name, classLoader);
Assert.isAssignable(type, instanceClass);
Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
T instance = BeanUtils.instantiateClass(constructor, args);
instances.add(instance);
} catch (Throwable var12) {
throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, var12);
}
ClassUtils.forName,name为加载类的全路径名称,通过ClassUtils.forName加载对应的类
通过 instanceClass.getDeclaredConstructor(parameterTypes); 表示传入无参的构造参数
示例此处的值为:new Class[0] ,
new Class[0]表示有零个元素的Class数组,即空数组,与传入null结果是一样的,都表示取得无参构造方法。
但是使用该方式可以避免抛出空异常。
BeanUtils.instantiateClass(constructor, args); 通过构造函数,入参实例化一个对象
org.springframework.util.ClassUtils#forName
public static Class<?> forName(String name, @Nullable ClassLoader classLoader) throws ClassNotFoundException, LinkageError
org.springframework.beans.BeanUtils#instantiateClass
instantiateClass(Constructor<T> ctor, Object... args)
自定义函数入参
函数参数调用方
示例位置:SpringApplicationRunListeners#starting
this.doWithListeners("spring.boot.application.starting", (listener) -> {
listener.starting(bootstrapContext);
}, (step) -> {
if (mainApplicationClass != null) {
step.tag("mainApplicationClass", mainApplicationClass.getName());
}
});
函数参数定义方
private void doWithListeners(String stepName, Consumer<SpringApplicationRunListener> listenerAction, Consumer<StartupStep> stepAction) {
StartupStep step = this.applicationStartup.start(stepName);
this.listeners.forEach(listenerAction);
if (stepAction != null) {
stepAction.accept(step);
}
step.end();
}
}
springboot 监听器扩展点混合使用
bean的生命周期和run的执行顺序
通过ApplicationContextInitializer 添加FactoryPostProcessor
主要依赖于bean的生命周期,context的加载、初始化、执行在FactoryPostProcessor扩展点之前执行,所以可以通过ApplicationContextInitializer扩展点动态添加扩展点。另一方面可以从beanFactory中拿到bean的信息和context的信息
java
class SharedMetadataReaderFactoryContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {
public static final String BEAN_NAME = "org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory";
SharedMetadataReaderFactoryContextInitializer() {
}
public void initialize(ConfigurableApplicationContext applicationContext) {
BeanFactoryPostProcessor postProcessor = new SharedMetadataReaderFactoryContextInitializer.CachingMetadataReaderFactoryPostProcessor(applicationContext);
applicationContext.addBeanFactoryPostProcessor(postProcessor);
}
......
}
CachingMetadataReaderFactoryPostProcessor实现了BeanDefinitionRegistryPostProcessor接口,而BeanDefinitionRegistryPostProcessor接口又继承了BeanFactoryPostProcessor所以BeanDefinitionRegistryPostProcessor本身就是一个BeanFactory后置处理器
java
static class CachingMetadataReaderFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
private final ConfigurableApplicationContext context;
CachingMetadataReaderFactoryPostProcessor(ConfigurableApplicationContext context) {
this.context = context;
}
public int getOrder() {
return -2147483648;
}
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
利用同样的思路可以添加动态的ApplicationListenter等