Springboot入门(一)

1、Spring Boot简介

背景
J2EE笨重的开发、繁多的配置、低下的开发效率、复杂的的部署流程、第三方技术集成难度大。

解决
“Spring全家桶”时代:
Spring Boot -> J2EE一站式解决方案
Spring Cloud -> 分布式整体解决方案

简述——什么是Spring Boot?
Spring Boot来简化Spring应用开发,约定大于配置,去繁从简,just run就能创建一个独立的,产品级别的应用:

  1. 简化spring应用开发的一个框架
  2. 整个spring技术栈的一个大整合
  3. J2EE开发的一站式解决

优点
快速创建独立运行的Spring项目以及与主流框架集成
使用嵌入式的Servlet容器,应用无需发成war
starters自动依赖与版本控制
大量的自动配置,简化开发,也可以修改默认值
无需配置XML,无代码生成,开箱即用
准生产环境的运行时应用监控
与云计算的天然集成

2、微服务

什么是微服务?
简而言之,微服务架构风格是将单个应用程序开发为一套小型服务的方法,每个小型服务都在自己的流程中运行,并与轻量级机制(通常是HTTP资源API)进行通信。 这些服务围绕业务功能搭建,可通过全自动部署机制独立部署。有一个集中管理的最低限度的这些服务,可以用不同的编程语言和使用不同的数据存储技术。

  • 架构风格:服务微化
  • 一个应用应该是一组小型的服务:可以通过http的方式进行切割。

下面我们来对比一个单体应用与微服务架构
单体应用 all in one
在这里插入图片描述

  • 开发简单
  • 测试简单
  • 部署简单:直接打包成war包丢到tomcat
  • 扩展简单:把应用复制多份,部署到集群中,负载均衡时并发分配到各个应用中。

微服务
每一个功能元素都是一个可独立替换和可独立升级的软件单元。
在这里插入图片描述

在这里插入图片描述
图中每一个黑圆圈都是一个独立的功能单元,每个功能单元之间通过http进行通信,在对某一个单元进行操作时(升级,替换,移除等)不会影响到其他单元。这么多的功能模块如果真要我们来微化,创建那么多的项目来微化这些服务的时候,每个项目可能都是要整合各种场景,如果按照以前的方式再来构建项目,这么多模块,光创建项目,搭建环境就得花费好多时间。
面对这么大型的分布式应用,springboot可以帮我们快速的构建出一个应用,整个分布式应用网之间该怎么互调呢,用springclound进行网状互联互调,包括在分布式中间要进行一些流式计算,批处理怎么办呢,springclound data flow,也就是官方为我们整个应用想清楚了应用的整个出路。

创建项目

https://start.spring.io/
在这里插入图片描述
下载下来后,直接导入idea即可使用。

写一个hello,world!

导入`web`依赖
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
@RequestMapping("/hello")
@ResponseBody
public String hello(){
   return "hello world";
}

直接运行启动类,即可

//标注一个主程序类,说明这是一个springboot应用
@SpringBootApplication
public class SpringBoot01HelloworldApplication {
	public static void main(String[] args) {
		//spring应用启动起来
		SpringApplication.run(SpringBoot01HelloworldApplication.class, args);
	}
}

服务器上部署:
导入springboot maven插件:

        <!--可以将应用打包成一个可执行的jar包-->
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>

将项目打包,部署

java -jar spring-boot-01-helloworld-0.0.1-SNAPSHOT.jar

可以发现我们不用打成war,然后扔到tomcat里去运行了。解压这个可执行的jar,在BOOT-INF\lib下,我们能看到嵌入式tomcat的依赖,因此目标环境就不需要tomcat服务器了。

HelloWord探究

1.pom文件
父项目

<!--父项目-->
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.2.4.RELEASE</version>
	<relativePath/> <!-- lookup parent from repository -->
</parent>
进入spring-boot-starter-parent,发现还有一个父项目
<parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-dependencies</artifactId>
   <version>2.2.4.RELEASE</version>
   <relativePath>../../spring-boot-dependencies</relativePath>
 </parent>
 进入spring-boot-dependencies,发现
 它里面定义了很多依赖的版本,实际上它来真正管理spring boot应用的所有依赖版本;
 它是springboot的版本仲裁中心:以后我们导入依赖默认是不需要写版本
 (没有在dependencies里面管理的依赖自然需要声明版本号)

2.启动器

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

spring-boot-starter:springboot场景启动器
进入spring-boot-starter-web:发现帮我们导入了web模块正常运行所依赖的组件。包括:

starter,json,tomcat,validation,web,webmvc

springboot将所有的功能场景都抽取出来,做成一个个的starters(启动器),只需要在项目里面引入这些starter相关场景的所有依赖就都会导入进来。要用什么功能就导入什么场景的启动器。

如果我们想要要用JMS或者mq,那么就有mq的启动器spring-boot-starter-activemq,要做aop,我们就导入spring-boot-starter-aop。。。。
官网参考starter

https://docs.spring.io/spring-boot/docs/2.2.4.RELEASE/reference/html/using-spring-boot.html#using-boot-starter

主程序类

//标注一个主程序类,说明这是一个springboot应用
@SpringBootApplication
public class SpringBoot01HelloworldApplication {
	public static void main(String[] args) {
		//spring应用启动起来
		SpringApplication.run(SpringBoot01HelloworldApplication.class, args);
	}
}

@SpringBootApplicationspringboot应用标注在某个类上说明这个类是springboot的主配置类;springboot就应该运行这个类的main方法来启动springboot应用。
查看该注解:

@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}
)}
)

1.@SpringBootConfigurationSpringBoot配置类;
标注在类上,表示这是一个springboot的配置类
查看该注解:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration

@Configuration:配置类上标注这个注解,配置类相当于配置文件,配置类也是容器中的一个组件;@Component


老版springboot自动配置原理

2.@EnableAutoConfiguration:开启自动配置功能;
以前我们需要配置的东西,springboot帮我们自动配置;
查看该注解:

@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})

2.1@AutoConfigurationPackage:自动配置包
查看该注解:

@Import({Registrar.class}) 

spring的底层注解@Import,给容器中导入组件;
查看Registrar
发现它实现了接口ImportBeanDefinitionRegistrar@Import的使用方式之一,重点看registerBeanDefinitions方法:
将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到spring容器

2.2 @Import({AutoConfigurationImportSelector.class}):查看该注解的自动配置选择器
发现AutoConfigurationImportSelector实现了ImportSelector,@Import的另一种使用方式,重点看selectImports方法:

	@Override
	public String[] selectImports(AnnotationMetadata annotationMetadata) {
		AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
				.loadMetadata(this.beanClassLoader);
		AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
				annotationMetadata);
		return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
	}

selectImports 方法中调用了一个 getAutoConfigurationEntry() 方法。
调用链:在 getAutoConfigurationEntry() -> getCandidateConfigurations() -> loadFactoryNames()
在这里 loadFactoryNames() 方法传入了 EnableAutoConfiguration.class 这个参数。先记住这个参数,等下会用到。
在这里插入图片描述
loadFactoryNames() 中关键的三步:

  • 从当前项目的类路径中获取所有 jar类路径下的META-INF/spring.factories 这个文件下的信息。
  • 将上面获取到的信息封装成一个 Map 返回。
  • 从返回的 Map 中通过刚才传入的 EnableAutoConfiguration.class 参数,获取该 key 下的所有值
    在这里插入图片描述

META-INF/spring.factories 探究
我们来看一下 META-INF/spring.factories 这类文件是什么就不懵了。当然在很多第三方依赖中都会有这个文件,一般每导入一个第三方的依赖,除了本身的jar包以外,还会有一个 xxx-spring-boot-autoConfigure,这个就是第三方依赖自己编写的自动配置类。我们现在就以 spring-boot-autocongigure 这个依赖来说。
在这里插入图片描述可以看到 EnableAutoConfiguration 下面有很多类,这些就是我们项目进行自动配置的类。
一句话:将类路径下 META-INF/spring.factories 里面配置的所有 EnableAutoConfiguration 的值加入到 Spring 容器中。

这么多的配置类,明显有很多自动配置我们平常是没有使用到的,没理由全部都生效吧。
  举个例子,看其中一条配置:

   org.springframework.boot.autoconfigure.aop.AopAutoConfiguration

进入到AopAutoConfiguration类中:
在这里插入图片描述
于是,我们又看到了熟悉的@ConditionalOnXXX注解,这个AopAutoConfiguration类加载不加载完全由@ConditionalOnXXX注解们来控制!下面详细分析下加载条件:

  @ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)

解析:在我们自己工程的application.properties里,有spring.aop.auto=true时加载AopAutoConfiguration。但是缺少spring.aop.auto=true时,也可继续验证(matchIfMissing = true),并不直接放弃加载。

  @ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class,AnnotatedElement.class })

解析:在JVM运行时加载了EnableAspectJAutoProxy、Aspect、Advice、AnnotatedElement这些类后,才加载AopAutoConfiguration

@ConditionalOnXXX 这类springboot注解进去会发现是基于spring的@Conditional的

有了自动配置的AopAutoConfigurationAOP配置类,我们就可以省略下面的配置类了:

@EnableAspectJAutoProxy
@Configuration
public class MainConfigOfAOP {
    //业务逻辑类加入容器中
    @Bean
    public MathCalculator calculator(){
        return new MathCalculator();
    }
    //切面类加入容器中
    @Bean
    public LogAspects logAspects(){
        return new LogAspects();
    }
}

还有一个典型的例子:在学习servlet3.0整合springmvc的定义与接管Springmvc时,配置springmvc的配置类要么通过实现WebMvcConfigurer接口,要么继承WebMvcConfigurerAdapter,但是WebMvcAutoConfiguration通过实现WebMvcConfigurer接口帮我们把视图解析器,Filter等等;以前我们需要配置的东西,自动配置类都帮我们配置了。

org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值