国外做科普视频的网站,卡片式网站模板,3d建模素材网站,网站开发不懂英语文章目录
一#xff1a;SpringBoot的自动装配
1#xff1a;从run方法到入口类内容被注册到注解解读器中。
2#xff1a;解析入口类注解到加载Bean实例 大神链接#xff1a;作者有幸结识技术大神孙哥为好友#xff0c;获益匪浅。现在把孙哥视频分享给大家。 孙哥链接SpringBoot的自动装配
1从run方法到入口类内容被注册到注解解读器中。
2解析入口类注解到加载Bean实例 大神链接作者有幸结识技术大神孙哥为好友获益匪浅。现在把孙哥视频分享给大家。 孙哥链接孙哥个人主页 作者简介一个颜值99分只比孙哥差一点的程序员 本专栏简介话不多说让我们一起干翻SpringSecurity6 本文章简介话不多说让我们讲清楚SpringSecurity6中为什么在引入SpringSecurity之后所有的请求都需要先做登录认证才可以进行访问呢 一SpringBoot的自动装配
1从run方法到入口类内容被注册到注解解读器中。 public static void main(String[] args) {SpringApplication.run(AlibabaApplication.class, args);}然后走到了一个run方法 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));this.webApplicationType WebApplicationType.deduceFromClasspath();this.bootstrapRegistryInitializers new ArrayList(getSpringFactoriesInstances(BootstrapRegistryInitializer.class));setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));this.mainApplicationClass deduceMainApplicationClass();}随后我们查看具体的run方法 public ConfigurableApplicationContext run(String... args) {long startTime System.nanoTime();DefaultBootstrapContext bootstrapContext createBootstrapContext();ConfigurableApplicationContext context null;configureHeadlessProperty();SpringApplicationRunListeners listeners getRunListeners(args);listeners.starting(bootstrapContext, this.mainApplicationClass);try {ApplicationArguments applicationArguments new DefaultApplicationArguments(args);ConfigurableEnvironment environment prepareEnvironment(listeners, bootstrapContext, applicationArguments);Banner printedBanner printBanner(environment);context createApplicationContext();context.setApplicationStartup(this.applicationStartup);//准备解析工作prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);//真正的解析工作refreshContext(context);afterRefresh(context, applicationArguments);Duration timeTakenToStartup Duration.ofNanos(System.nanoTime() - startTime);if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);}listeners.started(context, timeTakenToStartup);callRunners(context, applicationArguments);}catch (Throwable ex) {if (ex instanceof AbandonedRunException) {throw ex;}handleRunFailure(context, ex, listeners);throw new IllegalStateException(ex);}try {if (context.isRunning()) {Duration timeTakenToReady Duration.ofNanos(System.nanoTime() - startTime);listeners.ready(context, timeTakenToReady);}}catch (Throwable ex) {if (ex instanceof AbandonedRunException) {throw ex;}handleRunFailure(context, ex, null);throw new IllegalStateException(ex);}return context;}
我们查看准备工作 private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments, Banner printedBanner) {context.setEnvironment(environment);postProcessApplicationContext(context);addAotGeneratedInitializerIfNecessary(this.initializers);applyInitializers(context);listeners.contextPrepared(context);bootstrapContext.close(context);if (this.logStartupInfo) {logStartupInfo(context.getParent() null);logStartupProfileInfo(context);}// Add boot specific singleton beansConfigurableListableBeanFactory beanFactory context.getBeanFactory();beanFactory.registerSingleton(springApplicationArguments, applicationArguments);if (printedBanner ! null) {beanFactory.registerSingleton(springBootBanner, printedBanner);}if (beanFactory instanceof AbstractAutowireCapableBeanFactory autowireCapableBeanFactory) {autowireCapableBeanFactory.setAllowCircularReferences(this.allowCircularReferences);if (beanFactory instanceof DefaultListableBeanFactory listableBeanFactory) {listableBeanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}}if (this.lazyInitialization) {context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());}context.addBeanFactoryPostProcessor(new PropertySourceOrderingBeanFactoryPostProcessor(context));if (!AotDetector.useGeneratedArtifacts()) {// Load the sourcesSetObject sources getAllSources();Assert.notEmpty(sources, Sources must not be empty);load(context, sources.toArray(new Object[0]));}listeners.contextLoaded(context);}getAllSources获取入口类的信息。放到sources这个Set集合里边然后去做load我们查看load方法。 protected void load(ApplicationContext context, Object[] sources) {if (logger.isDebugEnabled()) {logger.debug(Loading source StringUtils.arrayToCommaDelimitedString(sources));}BeanDefinitionLoader loader createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources);if (this.beanNameGenerator ! null) {loader.setBeanNameGenerator(this.beanNameGenerator);}if (this.resourceLoader ! null) {loader.setResourceLoader(this.resourceLoader);}if (this.environment ! null) {loader.setEnvironment(this.environment);}loader.load();}void load() {for (Object source : this.sources) {load(source);}}private void load(Object source) {Assert.notNull(source, Source must not be null);if (source instanceof Class? clazz) {load(clazz);return;}if (source instanceof Resource resource) {load(resource);return;}if (source instanceof Package pack) {load(pack);return;}if (source instanceof CharSequence sequence) {load(sequence);return;}throw new IllegalArgumentException(Invalid source type source.getClass());}private void load(Class? source) {if (isGroovyPresent() GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {// Any GroovyLoaders added in beans{} DSL can contribute beans hereGroovyBeanDefinitionSource loader BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class);((GroovyBeanDefinitionReader) this.groovyReader).beans(loader.getBeans());}if (isEligible(source)) {this.annotatedReader.register(source);}}到这里完成了一个重要的工作读取入口类中重要的信息包括注解包括入口类本身。将入口类中的注解注册到注解解读器annotationreader当中。
2解析入口类注解到加载Bean 真正解析Bean的工作是从refreshContext当中进行的。 private void refreshContext(ConfigurableApplicationContext context) {if (this.registerShutdownHook) {shutdownHook.registerApplicationContext(context);}refresh(context);}protected void refresh(ConfigurableApplicationContext applicationContext) {applicationContext.refresh();} 最后跑到了一个applicationContext的refresh方法当中。 Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {StartupStep contextRefresh this.applicationStartup.start(spring.context.refresh);// 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);StartupStep beanPostProcess this.applicationStartup.start(spring.context.beans.post-process);// Invoke factory processors registered as beans in the context.invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.registerBeanPostProcessors(beanFactory);beanPostProcess.end();// 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 Springs core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();contextRefresh.end();}}}
接下来会进行Bean处理的13方法其中一个比较关键的方法invokeBeanFactoryPostProcessors protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime// (e.g. through an Bean method registered by ConfigurationClassPostProcessor)if (!NativeDetector.inNativeImage() beanFactory.getTempClassLoader() null beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}} 这里边会对我们的入口类中的注解进行详细的解析和复杂调用。其中对这些注解进行解析的时候要用到了这么一个类AutoConfigurationImportSelector 我们可以从调用链路上去证明这件事情
main1 prio5 tid0x1 nidNA runnablejava.lang.Thread.State: RUNNABLEat org.springframework.boot.context.annotation.ImportCandidates.load(ImportCandidates.java:90)at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getCandidateConfigurations(AutoConfigurationImportSelector.java:180)at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getAutoConfigurationEntry(AutoConfigurationImportSelector.java:126)at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector$AutoConfigurationGroup.process(AutoConfigurationImportSelector.java:430)at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGrouping.getImports(ConfigurationClassParser.java:796)at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.processGroupImports(ConfigurationClassParser.java:726)at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorHandler.process(ConfigurationClassParser.java:697)at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:182)at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:415)at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:287)at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:344)at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:115)at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:779)at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:597)- locked 0x12a7 (a java.lang.Object)at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:733)at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:435)at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)at org.springframework.boot.SpringApplication.run(SpringApplication.java:1290)at com.dashu.AlibabaApplication.main(AlibabaApplication.java:10) 所以这个在自动装配的过程当中确实完成了SpringSecurity的自动加载和配置。