diff --git a/spring/springboot/SimpleApplicationEventMulticaster.md b/spring/springboot/SimpleApplicationEventMulticaster.md deleted file mode 100644 index e69de29..0000000 diff --git a/spring/springboot/springboot01.md b/spring/springboot/springboot01.md deleted file mode 100644 index 47b1e6c..0000000 --- a/spring/springboot/springboot01.md +++ /dev/null @@ -1,255 +0,0 @@ -## 启动简单流程 - -1. allowing for further customization -1. 创建一个依赖启动类的实例ApplicationContext -2. 注册一个CommandLinePropertySource用来解析参数,并应用在容器中 -3. 刷新应用上下文,加载单例。 -4. 处理CommandLineRunner - -一次实例化类 - -1. ApplicationContextInitializer -2. ApplicationListener -3. SpringApplicationRunListener - -# 启动 - -```java - public static void main(String[] args) { - SpringApplication.run(PlantformApplication.class, args); - } -``` - -# 运行 - -```java - /** - * Static helper that can be used to run a {@link SpringApplication} from the - * specified source using default settings. - * @param primarySource the primary source to load - * @param args the application arguments (usually passed from a Java main method) - * @return the running {@link ApplicationContext} - */ - public static ConfigurableApplicationContext run(Class primarySource, - String... args) { - return run(new Class[] { primarySource }, args); - } -``` - -```java - /** - * Static helper that can be used to run a {@link SpringApplication} from the - * specified sources using default settings and user supplied arguments. - * @param primarySources the primary sources to load - * @param args the application arguments (usually passed from a Java main method) - * @return the running {@link ApplicationContext} - */ - public static ConfigurableApplicationContext run(Class[] primarySources, - String[] args) { - return new SpringApplication(primarySources).run(args); - } -``` - -## 创建对象 - -```java -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)); - this.webApplicationType = WebApplicationType.deduceFromClasspath(); - setInitializers((Collection) getSpringFactoriesInstances( - ApplicationContextInitializer.class)); - setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); - this.mainApplicationClass = deduceMainApplicationClass(); - } - - private Collection getSpringFactoriesInstances(Class type, - Class[] parameterTypes, Object... args) { - ClassLoader classLoader = getClassLoader(); - // Use names and ensure unique to protect against duplicates - Set names = new LinkedHashSet<>( - SpringFactoriesLoader.loadFactoryNames(type, classLoader)); - List instances = createSpringFactoriesInstances(type, parameterTypes, - classLoader, args, names); - AnnotationAwareOrderComparator.sort(instances); - return instances; - } -``` - -## run - -```java - public ConfigurableApplicationContext run(String... args) { - StopWatch stopWatch = new StopWatch(); - stopWatch.start(); - ConfigurableApplicationContext context = null; - Collection 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); - } - 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; - } - - private SpringApplicationRunListeners getRunListeners(String[] args) { - Class[] types = new Class[] { SpringApplication.class, String[].class }; - return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances( - SpringApplicationRunListener.class, types, this, args)); - } - private ConfigurableEnvironment prepareEnvironment( - SpringApplicationRunListeners listeners, - ApplicationArguments applicationArguments) { - // Create and configure the environment - ConfigurableEnvironment environment = getOrCreateEnvironment(); - configureEnvironment(environment, applicationArguments.getSourceArgs()); - listeners.environmentPrepared(environment); - bindToSpringApplication(environment); - if (!this.isCustomEnvironment) { - environment = new EnvironmentConverter(getClassLoader()) - .convertEnvironmentIfNecessary(environment, deduceEnvironmentClass()); - } - ConfigurationPropertySources.attach(environment); - return environment; - } - private Collection getSpringFactoriesInstances(Class type, - Class[] parameterTypes, Object... args) { - ClassLoader classLoader = getClassLoader(); - // Use names and ensure unique to protect against duplicates - Set names = new LinkedHashSet<>( - SpringFactoriesLoader.loadFactoryNames(type, classLoader)); - List instances = createSpringFactoriesInstances(type, parameterTypes, - classLoader, args, names); - AnnotationAwareOrderComparator.sort(instances); - return instances; - } - private void prepareContext(ConfigurableApplicationContext context, - ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, - ApplicationArguments applicationArguments, Banner printedBanner) { - context.setEnvironment(environment); - postProcessApplicationContext(context); - applyInitializers(context); - listeners.contextPrepared(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 sources = getAllSources(); - Assert.notEmpty(sources, "Sources must not be empty"); - load(context, sources.toArray(new Object[0])); - listeners.contextLoaded(context); - } - - public void refresh() throws BeansException, IllegalStateException { - synchronized (this.startupShutdownMonitor) { - // Prepare this context for refreshing. - prepareRefresh(); - - // Tell the subclass to refresh the internal bean factory. - ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); - - // Prepare the bean factory for use in this context. - prepareBeanFactory(beanFactory); - - try { - // Allows post-processing of the bean factory in context subclasses. - postProcessBeanFactory(beanFactory); - - // Invoke factory processors registered as beans in the context. - invokeBeanFactoryPostProcessors(beanFactory); - - // Register bean processors that intercept bean creation. - registerBeanPostProcessors(beanFactory); - - // Initialize message source for this context. - initMessageSource(); - - // Initialize event multicaster for this context. - initApplicationEventMulticaster(); - - // Initialize other special beans in specific context subclasses. - onRefresh(); - - // Check for listener beans and register them. - registerListeners(); - - // Instantiate all remaining (non-lazy-init) singletons. - finishBeanFactoryInitialization(beanFactory); - - // Last step: publish corresponding event. - 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(); - } - } - } -``` - diff --git a/spring/springboot/主体脉络.md b/spring/springboot/主体脉络.md new file mode 100644 index 0000000..8c9ab22 --- /dev/null +++ b/spring/springboot/主体脉络.md @@ -0,0 +1,21 @@ +### Create a new SpringApplication instance. + +1. 配置资源加载器 +2. 主类加载器 +3. 设置应用类型 +4. 实例化上下文ApplicationContextInitializer +5. 实例化监听器ApplicationListener +6. 查找主函数 + +### Run the Spring application, creating and refreshing a new ApplicationContext. + +1. 设置头信息java.awt.headless +2. 创建运行监听器 SpringApplicationRunListener +2. 准备环境ConfigurableEnvironment +2. 初始化上下文ConfigurableApplicationContext +2. 准备上下文 +2. 刷新上下文 +2. 启动监听器ApplicationListener +2. 启动ApplicationRunner + + diff --git a/spring/springboot/启动.md b/spring/springboot/启动.md index 65c00af..0b553b3 100644 --- a/spring/springboot/启动.md +++ b/spring/springboot/启动.md @@ -4,10 +4,6 @@ Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$69797ab5] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) ``` - - - - ```java SpringApplication.run(PrimarySources.class, args); ``` @@ -17,6 +13,8 @@ new SpringApplication(primarySources) setInitializers ApplicationContextInitializer.class setListeners ApplicationListener.class Class.forName(stackTraceElement.getClassName()) + +getSpringFactoriesInstances从META-INF/spring.factories获取实例通过反射创建 private static Map> loadSpringFactories(@Nullable ClassLoader classLoader) { MultiValueMap result = (MultiValueMap)cache.get(classLoader); if (result != null) { @@ -84,7 +82,8 @@ listeners.starting() DefaultApplicationArguments (new SimpleCommandLineArgsParser()).parse(args) ``` -```java -``` +准备环境 + +设置转换器 diff --git a/spring/springboot/获取工厂实例.md b/spring/springboot/获取工厂实例.md new file mode 100644 index 0000000..71d534e --- /dev/null +++ b/spring/springboot/获取工厂实例.md @@ -0,0 +1,89 @@ +## 获取类实例 + +```java + private Collection getSpringFactoriesInstances(Class type) { + return getSpringFactoriesInstances(type, new Class[] {}); + } + + private Collection getSpringFactoriesInstances(Class type, + Class[] parameterTypes, Object... args) { + ClassLoader classLoader = getClassLoader(); + // Use names and ensure unique to protect against duplicates + Set names = new LinkedHashSet<>( + SpringFactoriesLoader.loadFactoryNames(type, classLoader)); + List instances = createSpringFactoriesInstances(type, parameterTypes, + classLoader, args, names); + AnnotationAwareOrderComparator.sort(instances); + return instances; + } +``` + +## spring工厂中加载类名 + +```java + public static List loadFactoryNames(Class factoryType, @Nullable ClassLoader classLoader) { + String factoryTypeName = factoryType.getName(); + return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList()); + } +``` + +```java + private static Map> loadSpringFactories(@Nullable ClassLoader classLoader) { + MultiValueMap result = (MultiValueMap)cache.get(classLoader); + if (result != null) { + return result; + } else { + try { + Enumeration urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories"); + MultiValueMap result = new LinkedMultiValueMap(); + + while(urls.hasMoreElements()) { + URL url = (URL)urls.nextElement(); + UrlResource resource = new UrlResource(url); + Properties properties = PropertiesLoaderUtils.loadProperties(resource); + Iterator var6 = properties.entrySet().iterator(); + + while(var6.hasNext()) { + Map.Entry entry = (Map.Entry)var6.next(); + String factoryTypeName = ((String)entry.getKey()).trim(); + String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue()); + int var10 = var9.length; + + for(int var11 = 0; var11 < var10; ++var11) { + String factoryImplementationName = var9[var11]; + result.add(factoryTypeName, factoryImplementationName.trim()); + } + } + } + + cache.put(classLoader, result); + return result; + } catch (IOException var13) { + throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13); + } + } + } +``` + + + +```java + private List createSpringFactoriesInstances(Class type, Class[] parameterTypes, + ClassLoader classLoader, Object[] args, Set names) { + List 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; + } +``` + diff --git a/spring/事务手动回滚.md b/spring/spring源码解读/事务手动回滚.md similarity index 100% rename from spring/事务手动回滚.md rename to spring/spring源码解读/事务手动回滚.md