当前位置: 首页 > news >正文

南京做网站seo百度推广

南京做网站,seo百度推广,关于做暧暧的网站,网站中的自助报价系统文章目录 前言一、SpringBoot优势概要二、SpringBoot自动配置1. ☠注意☠2.自动配置详解 三、Starter(场景启动器)原理总结 前言 本文详细解析面试重点—SpringBoot自动配置原理、场景启动器原理,深入源码,直接上干货、绝不拖泥带…

文章目录

  • 前言
  • 一、SpringBoot优势概要
  • 二、SpringBoot自动配置
    • 1. ☠注意☠
    • 2.自动配置详解
  • 三、Starter(场景启动器)原理
  • 总结


前言

本文详细解析面试重点—SpringBoot自动配置原理、场景启动器原理,深入源码,直接上干货、绝不拖泥带水。


一、SpringBoot优势概要

一句话:约定大于配置,简化Spring的简化

  • 内嵌Web服务器
  • 环境启动器starter的使用,简化构建配置
  • 无需编写繁琐XML文件

二、SpringBoot自动配置

1. ☠注意☠

首先,要明确自动配置和自动装配的区别。
自动装配是SpringBoot的概念,是通过条件注解和配置元数据的方式,根据应用程序的依赖和环境,自动为应用程序进行配置。
自动装配是Spring的概念,是Spring框架通过依赖注入(Dependency Injection)机制来实现的,它通过自动根据类型或名称匹配来自动关联和装配Bean。

!!!!网络上有很多文章、视频张嘴就是SpringBoot的自动装配,这些基本不用看了,属实有些乐色!

2.自动配置详解

  • 创建一个SpringBoot2项目用作示例:

主配置类:

package com.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringBootTestApplication {public static void main(String[] args) {SpringApplication.run(SpringBootTestApplication.class, args);}}

POM文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.0</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>SpringBoot-Test</artifactId><version>0.0.1-SNAPSHOT</version><name>SpringBoot-Test</name><description>SpringBoot-Test</description><properties><java.version>8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
  • 项目结构分析

通过主配置类可以看出SpringBoot的最重要注解是@SpringBootApplication
通过POM文件可知SpringBoot项目的父项目是spring-boot-starter-parent

  • @SpringBootApplication详解

在IDEA中按住CTRL键进入@SpringBootApplication注解:

package org.springframework.boot.autoconfigure;import ...;@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {@Filter(type = FilterType.CUSTOM,classes = {TypeExcludeFilter.class}
), @Filter(type = FilterType.CUSTOM,classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {@AliasFor(annotation = EnableAutoConfiguration.class)Class<?>[] exclude() default {};...... 
}

可以看到@SpringBootApplication主要由:
@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan注解构成

我们逐个分析以上三个注解:

1. @SpringBootConfiguration注解
源码:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@Indexed
public @interface SpringBootConfiguration {@AliasFor(annotation = Configuration.class)boolean proxyBeanMethods() default true;
}

可以看出该注解由@Configuration注解和其他注解组成,所以,该注解的作用和@Configuration注解作用相似,代表当前是一个SpringBoot配置类。

2. @EnableAutoConfiguration注解
源码:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";Class<?>[] exclude() default {};String[] excludeName() default {};
}

该注解包含的注解主要有:@AutoConfigurationPackage、@Import({AutoConfigurationImportSelector.class})

  • @AutoConfigurationPackage源码:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({Registrar.class})
public @interface AutoConfigurationPackage {String[] basePackages() default {};Class<?>[] basePackageClasses() default {};
}

可以看出@AutoConfigurationPackage通过内部的@Import注解向IOC容器中导入了类: Registrar.class

Registrar.class源码:

 static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {Registrar() {}public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]));}public Set<Object> determineImports(AnnotationMetadata metadata) {return Collections.singleton(new AutoConfigurationPackages.PackageImports(metadata));}}

发现,@AutoConfigurationPackage利用Registrar给容器中导入一系列组件,将主配置类所在包下的所有组件导入容器中。

  • @Import({AutoConfigurationImportSelector.class})源码:
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered{.......
}

发现AutoConfigurationImportSelector实现了DeferredImportSelector接口,这就不得不提一下@Import注解的使用方式了,可以看看这篇文章:
@Import三种使用方式
@Import作用是向IOC容器中导入组建,其中有一种就是实现ImportSelector接口,并实现其中的selectImports方法,该方法的作用是返回一个由想要导入IOC容器的对象组成的数组。

查看AutoConfigurationImportSelector中实现的selectImports方法:

public String[] selectImports(AnnotationMetadata annotationMetadata) {if (!this.isEnabled(annotationMetadata)) {return NO_IMPORTS;} else {AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}}

发现其中调用了getAutoConfigurationEntry方法,继续跟进:

    protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {if (!this.isEnabled(annotationMetadata)) {return EMPTY_ENTRY;} else {AnnotationAttributes attributes = this.getAttributes(annotationMetadata);List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);configurations = this.removeDuplicates(configurations);Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);this.checkExcludedClasses(configurations, exclusions);configurations.removeAll(exclusions);configurations = this.getConfigurationClassFilter().filter(configurations);this.fireAutoConfigurationImportEvents(configurations, exclusions);return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);}}

很明显,getAutoConfigurationEntry方法又调用了getCandidateConfigurations方法,继续深入:

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");return configurations;}

发现getCandidateConfigurations调用了SpringFactoriesLoader的loadFactoryNames方法:

    public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {ClassLoader classLoaderToUse = classLoader;if (classLoader == null) {classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();}String factoryTypeName = factoryType.getName();return (List)loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());}

此方法又调用了loadSpringFactories方法:

private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {Map<String, List<String>> result = (Map)cache.get(classLoader);if (result != null) {return result;} else {HashMap result = new HashMap();try {Enumeration urls = classLoader.getResources("META-INF/spring.factories");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()) {Entry<?, ?> entry = (Entry)var6.next();String factoryTypeName = ((String)entry.getKey()).trim();String[] factoryImplementationNames = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());String[] var10 = factoryImplementationNames;int var11 = factoryImplementationNames.length;for(int var12 = 0; var12 < var11; ++var12) {String factoryImplementationName = var10[var12];((List)result.computeIfAbsent(factoryTypeName, (key) -> {return new ArrayList();})).add(factoryImplementationName.trim());}}}result.replaceAll((factoryType, implementations) -> {return (List)implementations.stream().distinct().collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));});cache.put(classLoader, result);return result;} catch (IOException var14) {throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var14);}}}

可以看出其从META-INF/spring.factories位置来加载一个文件。默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件。经过一层层返回之后,使用@Import注解导入到IOC容器
3. @ComponentScan注解

@ComponentScan(excludeFilters = {@Filter(type = FilterType.CUSTOM,classes = {TypeExcludeFilter.class}
), @Filter(type = FilterType.CUSTOM,classes = {AutoConfigurationExcludeFilter.class}
)}

此注解作用是默认扫描主配置类所在包及其子包中的@Component注解及其衍生注解

三、Starter(场景启动器)原理

1. 什么是场景启动器

Spring Boot场景启动器(Starter)是Spring Boot框架提供的一种便利机制,用于快速引入和配置特定场景下所需的依赖项。每个场景启动器都是一个独立的Maven项目,它提供了一组相关的依赖和配置,以便简化和加速特定场景下的应用程序开发。

2. 场景启动器特点

  • 集成依赖项:每个场景启动器都定义了一组相关的依赖项。这些依赖项被认为在特定场景中非常有用,比如Web开发、数据库访问、消息队列等等。通过使用场景启动器,开发者可以快速引入和配置所需的依赖项,而无需手动添加和管理这些依赖项。
  • 自动配置:场景启动器还提供了一些默认的自动配置,旨在简化特定场景下的配置工作。这些自动配置通常基于Spring Boot的条件注解和配置元数据机制,根据应用程序的依赖和环境来自动配置必要的组件和选项。通过使用场景启动器,开发者可以快速启动和运行基本的应用程序,而无需过多关注和编写配置代码。
  • 统一引入和管理:场景启动器通过简化和标准化依赖项的引入和配置,提供了一种统一的方式来解决常见的开发场景。开发者可以通过在项目的pom.xml文件中添加相应的场景启动器依赖,一次性引入和管理所有相关的依赖项,从而简化了项目的依赖管理和版本冲突的问题。

3. 以spring-boot-starter-web为示例

import ....;@Configuration(proxyBeanMethods = false
)
@ConditionalOnWebApplication(type = Type.SERVLET
)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {public static final String DEFAULT_PREFIX = "";public static final String DEFAULT_SUFFIX = "";private static final String SERVLET_LOCATION = "/";public WebMvcAutoConfiguration() {}@Bean@ConditionalOnMissingBean({HiddenHttpMethodFilter.class})@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter",name = {"enabled"})public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {return new OrderedHiddenHttpMethodFilter();}@Bean@ConditionalOnMissingBean({FormContentFilter.class})@ConditionalOnProperty(prefix = "spring.mvc.formcontent.filter",name = {"enabled"},matchIfMissing = true)public OrderedFormContentFilter formContentFilter() {return new OrderedFormContentFilter();}static class OptionalPathExtensionContentNegotiationStrategy implements ContentNegotiationStrategy {private static final String SKIP_ATTRIBUTE = PathExtensionContentNegotiationStrategy.class.getName() + ".SKIP";private final ContentNegotiationStrategy delegate;OptionalPathExtensionContentNegotiationStrategy(ContentNegotiationStrategy delegate) {this.delegate = delegate;}public List<MediaType> resolveMediaTypes(NativeWebRequest webRequest) throws HttpMediaTypeNotAcceptableException {Object skip = webRequest.getAttribute(SKIP_ATTRIBUTE, 0);return skip != null && Boolean.parseBoolean(skip.toString()) ? MEDIA_TYPE_ALL_LIST : this.delegate.resolveMediaTypes(webRequest);}}static class ResourceChainResourceHandlerRegistrationCustomizer implements WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer {private final Resources resourceProperties;ResourceChainResourceHandlerRegistrationCustomizer(Resources resourceProperties) {this.resourceProperties = resourceProperties;}

以上文中的SpringBoot自动配置为基础,可知SpringBoot会扫描我们引入的依赖中的META-INF目录下的spring.factories文件中以EnableAutoConfiguration为key的值,将其加入到IOC容器中,但是并不是所有的对象都会加入到IOC容器中,应为这些starter的主配置类中都会有@Conditional注解来指定约束条件:

  • @ConditionalOnBean:当容器里有指定 Bean 的条件下
  • @ConditionalOnMissingBean:当容器里没有指定 Bean 的情况下
  • @ConditionalOnSingleCandidate:当指定 Bean 在容器中只有一个,或者虽然有多个但是指定首选 Bean
  • @ConditionalOnClass:当类路径下有指定类的条件下
  • @ConditionalOnMissingClass:当类路径下没有指定类的条件下
  • @ConditionalOnProperty:指定的属性是否有指定的值
  • @ConditionalOnResource:类路径是否有指定的值
  • @ConditionalOnExpression:基于 SpEL 表达式作为判断条件
  • @ConditionalOnJava:基于 Java 版本作为判断条件
  • @ConditionalOnJndi:在 JNDI 存在的条件下差在指定的位置
  • @ConditionalOnNotWebApplication:当前项目不是 Web 项目的条件下
  • @ConditionalOnWebApplication:当前项目是 Web 项 目的条件下

4. starter整体结构
xxxAutoConfiguration:starter中的主配置类,其中定义了特定条件和默认配置文件的指定
xxxProperties:默认文件,可以在我们使用starter的时候进行配置覆盖,这里重点体现了springboot的约定大于配置。

总结

SpringBoot 使用@EnableAutoConfiguration开启自动配置功能,通过@Import注解加载实现了ImportSelector接口的类并最终加载META-INF/spring.factories中的自动配置类实现自动装配,自动配置类其实就是通过@Conditional按需加载的配置类,想要其生效必须引入spring-boot-starter-xxx包实现起步依赖。


文章转载自:
http://dinncogalwegian.ydfr.cn
http://dinncocareen.ydfr.cn
http://dinncooverhaul.ydfr.cn
http://dinncobaddish.ydfr.cn
http://dinncobiro.ydfr.cn
http://dinncointake.ydfr.cn
http://dinncoaminobenzene.ydfr.cn
http://dinncozoniferous.ydfr.cn
http://dinncoplausible.ydfr.cn
http://dinncocryptobiote.ydfr.cn
http://dinncoimponderability.ydfr.cn
http://dinncovaccinia.ydfr.cn
http://dinncoectocommensal.ydfr.cn
http://dinncospirket.ydfr.cn
http://dinncophysique.ydfr.cn
http://dinncoytterbia.ydfr.cn
http://dinncosupracrustal.ydfr.cn
http://dinncoforethought.ydfr.cn
http://dinncobilliards.ydfr.cn
http://dinncomaladjustment.ydfr.cn
http://dinncocovey.ydfr.cn
http://dinncoseater.ydfr.cn
http://dinncooutpoint.ydfr.cn
http://dinncolingering.ydfr.cn
http://dinncorrb.ydfr.cn
http://dinncodiscontinue.ydfr.cn
http://dinncohorseplayer.ydfr.cn
http://dinncoaquiprata.ydfr.cn
http://dinncowillow.ydfr.cn
http://dinncophenylephrine.ydfr.cn
http://dinncocronk.ydfr.cn
http://dinncolarghetto.ydfr.cn
http://dinncohorntail.ydfr.cn
http://dinncoark.ydfr.cn
http://dinncogerbera.ydfr.cn
http://dinnconatriuretic.ydfr.cn
http://dinncosweet.ydfr.cn
http://dinncochicagoan.ydfr.cn
http://dinncospreading.ydfr.cn
http://dinncobackcross.ydfr.cn
http://dinncomoschate.ydfr.cn
http://dinncodipnoan.ydfr.cn
http://dinncoshina.ydfr.cn
http://dinncocrenellation.ydfr.cn
http://dinncoassault.ydfr.cn
http://dinncobenefit.ydfr.cn
http://dinncomatsu.ydfr.cn
http://dinncodesirability.ydfr.cn
http://dinncopedagogy.ydfr.cn
http://dinncovagina.ydfr.cn
http://dinncoproturan.ydfr.cn
http://dinncotrismegistus.ydfr.cn
http://dinncomemory.ydfr.cn
http://dinncosilas.ydfr.cn
http://dinncosittable.ydfr.cn
http://dinncoticky.ydfr.cn
http://dinncogenappe.ydfr.cn
http://dinncovolte.ydfr.cn
http://dinncosmacker.ydfr.cn
http://dinncodigestant.ydfr.cn
http://dinncoovibos.ydfr.cn
http://dinncosupranational.ydfr.cn
http://dinncostackable.ydfr.cn
http://dinncounderbrim.ydfr.cn
http://dinncomakimono.ydfr.cn
http://dinncopaperwork.ydfr.cn
http://dinncooversew.ydfr.cn
http://dinncosinarquist.ydfr.cn
http://dinncoparoxysm.ydfr.cn
http://dinncowirehaired.ydfr.cn
http://dinncolilium.ydfr.cn
http://dinncobehavioral.ydfr.cn
http://dinncoquadrature.ydfr.cn
http://dinncoessentially.ydfr.cn
http://dinncoalamein.ydfr.cn
http://dinncofascination.ydfr.cn
http://dinncolandwards.ydfr.cn
http://dinncochuridars.ydfr.cn
http://dinncorecidivism.ydfr.cn
http://dinncozinciferous.ydfr.cn
http://dinncostralsund.ydfr.cn
http://dinncobudget.ydfr.cn
http://dinncocabby.ydfr.cn
http://dinncoruritan.ydfr.cn
http://dinncofluctuant.ydfr.cn
http://dinncoaccomplished.ydfr.cn
http://dinncowonder.ydfr.cn
http://dinncomyeloblast.ydfr.cn
http://dinncoavertable.ydfr.cn
http://dinncoanisole.ydfr.cn
http://dinncooutstay.ydfr.cn
http://dinncosubline.ydfr.cn
http://dinncoprivilege.ydfr.cn
http://dinnconippy.ydfr.cn
http://dinncocabotine.ydfr.cn
http://dinncodisequilibrium.ydfr.cn
http://dinncohomolysis.ydfr.cn
http://dinncocomputerese.ydfr.cn
http://dinncoimportant.ydfr.cn
http://dinncocomanagement.ydfr.cn
http://www.dinnco.com/news/92455.html

相关文章:

  • 网站优化原理汕头seo网站建设
  • saas平台seo网站推广多少钱
  • 医院网站后台管理系统登录如何搭建个人网站
  • PK10如何自己做网站百度合伙人官网app
  • 嘉兴建设局网站广州aso优化
  • 有网站后台模板如何做数据库怎么找需要做推广的公司
  • 自己做的网站怎么接入网页游戏谷歌浏览器官网手机版
  • 个人网站如何获得流量上海快速优化排名
  • 公司注册地址在外地却在本地经营汉川seo推广
  • 装饰公司网站北京网站优化指导
  • wordpress前台代码编辑器上海网站seo公司
  • 规划建立一个网站百度快照网址
  • 嘉兴公司制作网站的如何营销
  • 个人 申请域名做网站中山seo推广优化
  • wordpress自动同步插件怀来网站seo
  • 网站建设 价格百度推广效果怎么样
  • 吉化北建公司官网西青seo
  • 做网站原创要多少钱外贸快车
  • 做网站交互demo工具唐山seo优化
  • 网站的开发环境设计美国seo薪酬
  • 淮北网站建设网上销售平台有哪些
  • 去哪个网站有客户找做标书的2023年10月疫情还会严重吗
  • 网站排名带照片怎么做中公教育培训机构官网
  • 用asp制作一个简单的网站微指数查询
  • 网站建设v地推平台去哪里找
  • 武汉门户网站建设网络的推广
  • 吉林建设厅网站网站搜什么关键词好
  • 网站备案要多久推广策略都有哪些
  • 做网址导航网站收益北京网络推广优化公司
  • 用dw怎么做网站后台优化大师免费安装下载