一 SpringBoot和SSM的区别

传统的SSM框架的问题:
1,初始化配置
为了使用SSM框架去开发,需要准备ssm框架的模板配置,
2整合第三方框架
为了spring 整合第三方框架,单独的去编写xml文件
3 后期维护
后期SSM项目后期xml文件特别多,维护xml文件的成本是很高的
4部署工程
SSM工程部署也是很麻烦的,依赖第三方的容器
spring boot :
简介:spring boot并不是一门新技术,只是将之前的spring ,springMVC,data-jpa等常用的框架封装到了一起,帮助隐藏这些框架的整合细节,实现敏捷开发。
spring boot 就是一个工具集。
spring boot特点:

  1. spring boot项目中不需要模板化的配置,
  2. spring boot 整合第三方框架时,只需要导入相应的starter依赖包,就自动整合了。
  3. spring boot 默认只有一个.properties的配置文件, 不推荐使用xml,后期会采用.Java的文件去编写配置信息;
  4. spring boot 工程在部署的时,采用的时jar包的方式,内部自动依赖tomcat容器,提供了多环境的配置
  5. 微服务框架spring cloud建立在spring boot的基础之上

    二 自动装配的原理

    springboot的一大优势就是省去了很多的配置,也就是说当springboot启动的时候,springboot在内部就已经帮忙封装好了,这其实就是springboot的自动装配操作。
    1 从@SpringBootApplication启动注解入手
    源码 ```java @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 {}; @AliasFor(annotation = EnableAutoConfiguration.class) String[] excludeName() default {}; //根据包路径扫描 @AliasFor(annotation = ComponentScan.class, attribute = “basePackages”) String[] scanBasePackages() default {}; //直接根据class类扫描 @AliasFor(annotation = ComponentScan.class, attribute = “basePackageClasses”) Class<?>[] scanBasePackageClasses() default {};

}

  1. 初看@SpringBootApplication有很多的注解组成,其实归纳起来就是一个“三体”结构,重要的只有三个注解:
  2. ```java
  3. @Configuration(@SpringBootConfiguration实质就是一个@Configuration)
  4. @EnableAutoConfiguration
  5. @ComponentScan

也就是说在我们开发的时候,加上这三个注解==@SpringBootApplication注解
@Configuration注解

代表是一个配置类,相当于beans.xml文件,
@ComponentScan
其功能就是自动扫描并加载符合条件的组件或bean定义,最终将bean定义加载到容器中
@EnableAutoConfiguration
在spring中有关@Enablexxx的注解是开启某一项功能的注解,比如:@EnableScheduling表示开启spring的定时任务。其原理是借助@import的帮助,将所有符合自动配置条件的bean定义加载到IOC容器。
@EnableAutoConfiguration代表开启springboot的自动装配

  1. @Target(ElementType.TYPE)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. @Inherited
  5. @AutoConfigurationPackage
  6. @Import(AutoConfigurationImportSelector.class)
  7. public @interface EnableAutoConfiguration {
  8. String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
  9. //按类型排序不需要自动装配的类
  10. Class<?>[] exclude() default {};
  11. //按名称排除不需要自动装配的类
  12. String[] excludeName() default {};
  13. }

从源码中可以知道,最关键的要属@Import(EnableAutoConfigurationImportSelector.class),借助EnableAutoConfigurationImportSelector,@EnableAutoConfiguration可以帮助SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot创建并使用的IoC容器。同时借助于Spring框架原有的一个工具类:SpringFactoriesLoader,@EnableAutoConfiguration就可以实现智能的自动配置。

  1. //从这里可以看出该类实现很多的xxxAware和DeferredImportSelector,所有的aware都优先于selectImports
  2. //方法执行,也就是说selectImports方法最后执行,那么在它执行的时候所有需要的资源都已经获取到了
  3. public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
  4. ...
  5. public String[] selectImports(AnnotationMetadata annotationMetadata) {
  6. if (!this.isEnabled(annotationMetadata)) {
  7. return NO_IMPORTS;
  8. } else {
  9. //1加载META-INF/spring-autoconfigure-metadata.properties文件
  10. AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
  11. //2获取注解的属性及其值(PS:注解指的是@EnableAutoConfiguration注解)
  12. AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
  13. //3.在classpath下所有的META-INF/spring.factories文件中查找org.springframework.boot.autoconfigure.EnableAutoConfiguration的值,并将其封装到一个List中返回
  14. List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
  15. //4.对上一步返回的List中的元素去重、排序
  16. configurations = this.removeDuplicates(configurations);
  17. //5.依据第2步中获取的属性值排除一些特定的类
  18. Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
  19. //6对上一步中所得到的List进行过滤,过滤的依据是条件匹配。这里用到的过滤器是
  20. //org.springframework.boot.autoconfigure.condition.OnClassCondition最终返回的是一个ConditionOutcome[]
  21. //数组。(PS:很多类都是依赖于其它的类的,当有某个类时才会装配,所以这次过滤的就是根据是否有某个
  22. //class进而决定是否装配的。这些类所依赖的类都写在META-INF/spring-autoconfigure-metadata.properties文件里)
  23. this.checkExcludedClasses(configurations, exclusions);
  24. configurations.removeAll(exclusions);
  25. configurations = this.filter(configurations, autoConfigurationMetadata);
  26. this.fireAutoConfigurationImportEvents(configurations, exclusions);
  27. return StringUtils.toStringArray(configurations);
  28. }
  29. }
  30. protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
  31. List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
  32. 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.");
  33. return configurations;
  34. }
  35. ...
  36. }

SpringFactoriesLoader中加载配置,SpringFactoriesLoader属于Spring框架私有的一种扩展方案,其主要功能就是从指定的配置文件META-INF/spring.factories加载配置,即根据@EnableAutoConfiguration的完整类名org.springframework.boot.autoconfigure.EnableAutoConfiguration作为查找的Key,获取对应的一组@Configuration类

  1. public abstract class SpringFactoriesLoader {
  2. public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
  3. private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
  4. MultiValueMap<String, String> result = cache.get(classLoader);
  5. if (result != null)
  6. return result;
  7. try {
  8. Enumeration<URL> urls = (classLoader != null ?
  9. classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
  10. ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
  11. result = new LinkedMultiValueMap<>();
  12. while (urls.hasMoreElements()) {
  13. URL url = urls.nextElement();
  14. UrlResource resource = new UrlResource(url);
  15. Properties properties = PropertiesLoaderUtils.loadProperties(resource);
  16. for (Map.Entry<?, ?> entry : properties.entrySet()) {
  17. List<String> factoryClassNames = Arrays.asList(
  18. StringUtils.commaDelimitedListToStringArray((String) entry.getValue()));
  19. result.addAll((String) entry.getKey(), factoryClassNames);
  20. }
  21. }
  22. cache.put(classLoader, result);
  23. return result;
  24. }
  25. catch (IOException ex) {
  26. throw new IllegalArgumentException("Unable to load factories from location [" +
  27. FACTORIES_RESOURCE_LOCATION + "]", ex);
  28. }
  29. }
  30. ...

总结:@EnableAutoConfiguration作用就是从classpath中搜寻所有的META-INF/spring.factories配置文件,并将其中org.springframework.boot.autoconfigure.EnableutoConfiguration对应的配置项通过反射(Java Refletion)实例化为对应的标注了@Configuration的JavaConfig形式的IoC容器配置类,然后汇总为一个并加载到IoC容器。这些功能配置类要生效的话,会去classpath中找是否有该类的依赖类(也就是pom.xml必须有对应功能的jar包才行)并且配置类里面注入了默认属性值类,功能类可以引用并赋默认值。生成功能类的原则是自定义优先,没有自定义时才会使用自动装配类。

  • 所以功能类能生效需要的条件:(1)spring.factories里面有这个类的配置类(一个配置类可以创建多个围绕该功能的依赖类)(2)pom.xml里面需要有对应的jar包

作者:小manong
链接:https://www.jianshu.com/p/88eafeb3f351
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

三 核心注解

1 @Contiguration,@Bean
之前使用SSM去开发时,在xml文件中编写bean标签,但是spring boot不推荐使用xml文件

  • @Configuration注解相当于beans标签
  • @Bean注解相当于bean标签
  • id=”方法名|注解中的name属性(优先级更高)”;
  • class=”方法的返回结果”

    1. @Configuration // 代表当前类是一个配置类
    2. public class UserConfig {
    3. @Bean(name = "user1") // 构建一个实例,放到spring容器中
    4. public User user(){
    5. User user = new User();
    6. user.setId(1);
    7. user.setName("张三");
    8. return user;
    9. }
    10. /*
    11. <beans ....> @Configuration
    12. <bean id="user1" class="com.qf.firstspringboot.entity.User" />
    13. </beans>
    14. */
    15. }

    2 @SpringBootApplication(标注是一个springboot应用)

  • @SpringBootApplication是一个组合注解:

  • @SpringBootApplication就是一个@Configuration注解,代表启动类就是一个配置类
  • @EnableAutoConfiguration帮助实现自动装配的,spring boot项目启动时,运行一个SpringFactoriesLoader的类,加载META1-INF/spring。factories配置类(已经开启的),通过SpringFactoriesLoader中的load方法,以for循环的方式,一个一个的加载。
  • 好处:无需编写大量的整合配置信息,只需要按照spring boot提供的约定去整合即可。
  • 坏处:如果你导入了一个starter依赖,就必须要填写他的配置信息
  • 手动关闭自动装配指定内容:@SpringBootApplication(exclude=QuarzAutoConfigration.class)
  • @ComponentScan就相当于,帮助扫描注@RestController //代替@Controller+@ResponseBodyy@RequestMapping(“”))//一个方法支持多种请求方式式式 @GetMapping(“”)//Get请求)解

@PostMapping(“”)//Post请求
@PutMapping(“”)//Put请求
@DeleteMapping(“”)//Delete请求

四 Spring-Boot-Starter![GH4BH07{0}UTB%%S@U0B.png

Spring-Boot-Starter:启动器
启动器就是springboot的启动场景,比如我们要使用web相关的,就直接引用spring-boot-starter-web,那么它就会帮我们自动导入web环境下所有必须的依赖。
以Spring-Boot-Starter为例:

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot</artifactId>
  4. <version>2.2.1.RELEASE</version>
  5. <scope>compile</scope>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-autoconfigure</artifactId>
  10. <version>2.2.1.RELEASE</version>
  11. <scope>compile</scope>
  12. </dependency>
  13. <dependency>
  14. <groupId>org.springframework.boot</groupId>
  15. <artifactId>spring-boot-starter-logging</artifactId>
  16. <version>2.2.1.RELEASE</version>
  17. <scope>compile</scope>
  18. </dependency>
  19. <dependency>
  20. <groupId>jakarta.annotation</groupId>
  21. <artifactId>jakarta.annotation-api</artifactId>
  22. <version>1.3.5</version>
  23. <scope>compile</scope>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.springframework</groupId>
  27. <artifactId>spring-core</artifactId>
  28. <version>5.2.1.RELEASE</version>
  29. <scope>compile</scope>
  30. </dependency>
  31. <dependency>
  32. <groupId>org.yaml</groupId>
  33. <artifactId>snakeyaml</artifactId>
  34. <version>1.25</version>
  35. <scope>runtime</scope>
  36. </dependency>

其中存放了自动配置相关的依赖,日志相关的依赖,spring-core等依赖,这些依赖只需要我们导入一个spring-boot-starter就可以直接将其全部引入,而不需要再像以前那样逐个导入了。
springboot会将所有的功能场景都封装一个一个的启动器,供开发人员使用。
使用的时候可以直接去官网上找需要的启动类,直接引入
获取启动类文档:https://link.zhihu.com/?target=https%3A//docs.spring.io/spring-boot/docs/2.2.1.RELEASE/reference/html/using-spring-boot.html%23using-boot-starter

五 前后端分离,如何维护接口文档


swagger是一个规范且完整的框架,用于生成,描述,调用和可视化restful风格的web服务。
Swagger 的目标是对 REST API 定义一个标准且和语言无关的接口,可以让人和计算机拥有无须访问源码、文档或网络流量监测就可以发现和理解服务的能力。当通过 Swagger 进行正确定义,用户可以理解远程服务并使用最少实现逻辑与远程服务进行交互。与为底层编程所实现的接口类似,Swagger 消除了调用服务时可能会有的猜测。

主程序

@SpringBootApplication 标注,是一个SpringBoot应用,在写springboot项目的时候总要写一个主程序,这个主程序的最大特点就是其类上放了一个@SpringBootApplication注解,这个注解是springboot项目启动的核心,
分析到这里,我们就可以得出一个完整的结论了:
当我们的SpringBoot项目启动的时候,会先导入AutoConfigurationImportSelector,这个类会帮我们选择所有候选的配置,我们需要导入的配置都是SpringBoot帮我们写好的一个一个的配置类,那么这些配置类的位置,存在与META-INF/spring.factories文件中,通过这个文件,Spring可以找到这些配置类的位置,于是去加载其中的配置。
image.png