SpringBoot2 基础入门
SpringBoot 简介
JavaEE开发的**
一站式
**解决方案! 简化Spring应用开发的一个框架,整个Spring技术栈的一个大整合;
SpringBoot时代背景
微服务
2014 ,martin fowler马丁·福勒
提出的:微服务架构**风格
** 常听的:分布式微服务
优点: 一个应用拆分为一组小型服务 每一个服务: 运行在自己的进程内,也就是可独立部署和升级,通过HTTP的方式进行互通; • 服务围绕业务功能拆分 • 可以由全自动部署机制独立部署 • 去中心化,服务自治。服务可以使用不同的语言、不同的存储技术;
只要实现功能即可~
上图:**微服务分布式架构,每一个点表示一个功能, 使用时只需要调用需要的功能模块组合即可!
**
缺点:
- 运维要求高: 更多的服务意味着要投入更多的运维。
- 分布式固有的复杂性: 使用微服务构建的是分布式系统。对于一个分布式系统,系统容错、网络延迟、 分布式事务等都会带来巨大的问题。
- 接口调整成本高: 微服务之间通过接口进行通信。 如果修改某一个微服务的API,可能所有用到这个接口的微服务都需要进行调整。 远程调用、服务发现、负载均衡、服务容错、配置管理、服务监控、链路追踪、日志管理、任务调度……
说到微服务架构,不得不提的就是 单体应用
单体应用
一个归档包(可以是JAR、WAR、EAR或其它归档格式)包含所有功能的应用程序,通常称为**
单体应用。
**
优点
- 便于共享: 单个归档文件包含所有功能,便于在团队之间以及不同的部署阶段之间共享。
- 易于测试: 单体应用一旦部署,所有的服务或特性就都可以使用了,这简化了测试过程。 因为没有额外的依赖,每项测试都可以在部署完成后立刻开始。
- 易于部署: 只需将单个归档文件复制到单个目录下。
缺点
- 复杂性高: 由于是单个归档文件,所以一个文件 等于 整个项目,文件包含的模块非常多,导致模块的边界模糊。 依赖关系不清晰、代码的质量参差不齐,混乱的堆在一起,使得整个项目非常复杂。 以致每次修改代码,都非常小心,可能添加一个简单的功能,或者修改一个Bug都会带来隐藏的缺陷。
- 技术债务: 随着时间的推移、需求的变更和技术人员的更替,会逐渐形成应用程序的技术债务,并且越积越多。
- 扩展能力受限: 单体应用只能作为一个整体进行扩展,无法根据业务模块的需要进行伸缩。 (为了提高项目性能可以, 将一个项目复制多份部署多台服务器~)
- 阻碍技术创新: 对于单体应用来说,技术是在开发之前经过慎重评估后选定的, 每个团队成员都必须使用相同的开发语言、持久化存储及消息系统。
SpringBoot2入门
环境约束
Java8 或以上 学习
Maven3.3 或以上 学习
本人使用的编辑器是: Idea2020
或其它编辑器,Spring官方的推荐的 STS
maven设置
settings.xml
文件修改配置~ Maven——conf目录下:
<!--
<!-- 阿里云仓库:提供大量组件,不配置自己联网下载到本地仓库~ -->
<mirrors>
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
<!-- 告诉Maven统一编辑项目 jdk1.8~ -->
<profiles>
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
</profiles>
什么是SpringBoot
Springboot是用于简化原始Spring的复杂 快速创建出生产级别的Spring应用,也是Spring技术栈的一站式框架。 本质上还是Spring,只不过将以往需要配置的信息封装到底层,使开发者更加快捷的搭建好环境。 因此被称为Spring的**
脚手架
**:
- 脚手架指的是两种技术之一: 第一种是与某些MVC 框架中的数据库访问相关的代码生成技术; 第二种是由各种工具支持的项目生成技术。
SpringBoot的优点
内嵌Web服务器 创建独立的Spring应用 无代码生成,无需编写XML 自动starter以来,简化构建配置 自动配置Spring以及第三方功能 提供生产级别的监控、健康检查以及外部化配置
SpringBoot缺点
人称版本帝,迭代快,需要时刻关注变化 封装太深,内部原理复杂,不容易精通
正片开始
好了,从现在开始我们可以迅速创建一个SpringBoot应用,
可以通过IDEA的快捷配置方式
同时也可以使用Maven直接配置,在这里只演示第二种方式。
HelloWorld!!
需求:浏览发送/hello请求,响应 Hello, Spring Boot 2
1.创建maven工程
引入依赖:
pom.xml
<!-- 集成一个父项目 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<!-- spring-boot对一些开发所需的资源Jar有自动的管理都存在在对应的 starter-xxx管理.
这里使用 spring-boot-starter-web 引入所有的web组件!
一切都由SpringBoot帮你做好了。
-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2.创建主程序
SpringBoot程序需要一个入口: 负责启动开启应用程序
- 主程序类一般声明在最外层包下,默认扫描所在包下的所有
类注解
方便初始化应用! - 这里提到很多新的注解,之前常用的MVC 注解依然可以使用, 根据喜好使用 可以多学习了解~
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication //标注主程序类,这是一个Springboot应用!
//@SpringBootApplication(scanBasePackages = "指定扫描包下注解~") //默认扫描该类的包及子包~
public class SpringBootRun {
public static void main(String[] args) {
//用来执行开启SpringBoot程序; 参数当前主程序类.class args
ConfigurableApplicationContext run = SpringApplication.run(SpringBootRun.class,args);
}
}
3.创建Controller控制器:
代码语言:javascript复制import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
//作用:该类是一个Controller控制器 且 下所有方法的返回值为一个JSON
//相当于是一个:@Controller 和 @ResponseBody 注解的集合,内部SpringBoot 自定义了完善的属性配置,当然也可以通过配置修改覆盖...
@RestController
public class HelloController {
//相当于: 以前SpringMVC的 @RequestMapping get方式请求~
//@RequestMapping(value = "/show" ,method = RequestMethod.GET)
@GetMapping(value = "/show") //@GetMapping用于处理请求方法的GET类型,@PostMapping用于处理请求方法的POST类型等。
public String Hello(){
return "Hello Wrod!!";
}
}
4. 启动主程序类:
每错直接启动即可:SpringBoot中有自带的集成运行环境容器;
可以清除的看到 Tomcat initialized with port(s): 8080 (http)
或打包控制台——部署运行(简化部署):
使用Maven 打包程序:
pom.xml
文件中加入
<!-- 使SpringBoot工程支持,项目打成jar包,直接在目标服务器执行即可 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.2.6.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
ok, 到这基本体现到 SpringBoot 应用程序的强大! 无须服务器!单体项目~ 强大注解生态资源自带集成~!!
SpringBoot特点
以下说明全部来源于 大佬!! 本人借鉴学习!
依赖管理
SpringBoot 对依赖管理非常强大!
在Spring Boot入门程序中,项目pom.xml文件有两个核心依赖~
分别是spring-boot-starter-parent
和spring-boot-starter-web
关于这两个依赖的相关介绍具体如下。
spring-boot-starter-parent
举例说明:**pom.xml
**
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
- 上述代码中,将spring-boot-starter-parent依赖作为Spring Boot项目的统一父项目依赖管理 并将项目版本号统一为2.1.6.RELEASE,该版本号根据实际开发需求是可以修改的。
- 使用**
Ctrl 鼠标左键
**进入并查看spring-boot-starter-parent底层源文件: - 发现spring-boot-starter-parent的底层有一个父依赖**
spring-boot-dependencies
**,核心代码具体如下。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
...
继续查看spring-boot-dependencies底层源文件,核心代码具体如下。
代码语言:javascript复制<properties>
<activemq.version>5.15.8</activemq.version>
...
<solr.version>7.4.0</solr.version>
<!-- Spring家族依赖组件~ -->
<spring.version>5.1.5.RELEASE</spring.version>
<spring-amqp.version>2.1.4.RELEASE</spring-amqp.version>
<spring-batch.version>4.1.1.RELEASE</spring-batch.version>
<spring-cloud-connectors.version>2.0.4.RELEASE</spring-cloud-connectors.version>
<spring-data-releasetrain.version>Lovelace-SR5</spring-data-releasetrain.version>
<spring-framework.version>${spring.version}</spring-framework.version>
<spring-security.version>5.1.4.RELEASE</spring-security.version>
<spring-session-bom.version>Bean-SR3</spring-session-bom.version>
<spring-ws.version>3.0.6.RELEASE</spring-ws.version>
<sqlite-jdbc.version>3.25.2</sqlite-jdbc.version>
<statsd-client.version>3.1.0</statsd-client.version>
<sun-mail.version>${javax-mail.version}</sun-mail.version>
<thymeleaf.version>3.0.11.RELEASE</thymeleaf.version>
<tomcat.version>9.0.16</tomcat.version> <!-- Tomcat -->
<unboundid-ldapsdk.version>4.0.9</unboundid-ldapsdk.version>
<undertow.version>2.0.17.Final</undertow.version>
<versions-maven-plugin.version>2.7</versions-maven-plugin.version>
<webjars-hal-browser.version>3325375</webjars-hal-browser.version>
<webjars-locator-core.version>0.35</webjars-locator-core.version>
</properties>
- 从**
spring-boot-dependencies
**底层源文件可以看出 该文件通过< properties >标签对一些常用技术框架的依赖文件进行了统一版本号管理, 例如 activemq、spring、tomcat等,都有与Spring Boot 2.1.3版本相匹配的版本, 这也是pom.xml引入依赖文件不需要标注依赖文件版本号的原因。 - 需要说明的是,如果pom.xml引入的依赖文件不是 spring-boot-starter-parent管理的,
- 那么在pom.xml引入依赖文件时,需要使用 < version > 标签指定依赖文件的版本号。
开发中见到很多:**见到很多 spring-boot-starter-*
**
spring-boot-starter-web 依赖
spring-boot-starter-parent父依赖启动器的主要作用是进行版本统一管理:
那么项目运行依赖的JAR包是从何而来?又是怎样管理的呢?
下面,查看项目pom.xml
文件中的spring-boot-starter-web
依赖。
查看**spring-boot-starter-web
**依赖文件源码,核心代码具体如下。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.1.3.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
<version>2.1.3.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.1.3.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.14.Final</version>
<scope>compile</scope>
</dependency>
<!-- .... -->
</dependencies>
spring-boot-starter-web依赖启动器的主要作用:
- 是提供Web开发场景所需的底层所有依赖文件, 它对Web开发场景所需的依赖文件进行了统一管理。
- 正是如此,在pom.xml中引入spring-boot-starter-web依赖启动器时,就可以实现Web场景开发 不需要额外导入Tomcat服务器以及其他Web依赖文件等。 当然,这些引入的依赖文件的版本号还是由spring-boot-starter-parent父依赖进行的统一管理。
Spring Boot除了提供有上述介绍的Web依赖启动器外,还提供了其他许多开发场景的相关依赖,我们可以打开Spring Boot官方文档,搜索“Starters”关键字查询场景依赖启动器,具体如下图所示。
@SpringBootApplication注解 自动装配原理
@SpringBootApplication注解表示Spring Boot启动类。
- Spring Boot应用的启动入口是@SpringBootApplication注解标注类中的main()方法 @SpringBootApplication能够扫描Spring组件并自动配置Spring Boot
- 查看@SpringBootApplication注解源码 :
按住: Ctrl @SpringBootApplication
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
//以上一些Java的注解无伤大雅!
@SpringBootConfiguration // 标明该类为配置类
@EnableAutoConfiguration // 启动自动配置功能
@ComponentScan( // 包扫描器
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
...
}
@SpringBootApplication注解是一个组合注解:
包含@SpringBootConfiguration
、@EnableAutoConfiguration
、@ComponentScan
三个核心注解
@SpringBootConfiguration注解
@SpringBootConfiguration注解表示类为: Spring Boot配置类
代码语言:javascript复制@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
@SpringBootConfiguration注解内部有一个核心注解@Configuration
- Spring框架提供的注解: 表示当前类为一个配置类(XML配置文件的注解表现形式)
- 并可以被组件扫描器扫描。 由此可见,@SpringBootConfiguration注解的作用与@Configuration注解相同
- 都是标识一个可以被组件扫描器扫描的配置类, 只不过@SpringBootConfiguration是被Spring Boot进行了重新封装命名而已。
@EnableAutoConfiguration注解
@EnableAutoConfiguration注解表示开启自动配置功能
该注解是Spring Boot框架最重要的注解,也是实现自动化配置的注解。
代码语言:javascript复制@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 {};
}
@EnableAutoConfiguration注解也是一个组合注解,
它主要包括有@AutoConfigurationPackage
和@Import
两个核心注解。
自己查看以下注解 Ctrl
- @AutoConfigurationPackage: @AutoConfigurationPackage注解的功能是由@Import注解实现的, 作用是向容器导入注册的所有组件,导入的组件由Registrar决定
- @Import({AutoConfigurationImportSelector.class}): 使用了这个注解,相当于 Java 中的 import 关键字,可以导入 Spring 的 bean 到 IOC 容器中。
@AutoConfigurationPackage:类
自动配置包?指定了默认的包规则
代码语言:javascript复制@Import(AutoConfigurationPackages.Registrar.class) //给容器中导入一个组件
public @interface AutoConfigurationPackage {}
//利用Registrar给容器中导入一系列组件
//将指定的一个包下的所有组件导入进来?MainApplication 所在包下。
查看AutoConfigurationImportSelector类的getAutoConfigurationEntry()方法,核心代码具体如下。
Ctrl F
Idea查看文本
protected AutoConfigurationImportSelector.AutoConfigurationEntry
getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
} else {
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
// 获取所有Spring Boot提供的后续自动配置类XxxAutoConfiguration
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);
// 筛选并过滤出当前应用环境下需要的自动配置类XxxAutoConfiguration
configurations = this.filter(configurations, autoConfigurationMetadata);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationImportSelector.AutoConfigurationEntry(
configurations, exclusions);
}
}
在上述展示的getAutoConfigurationEntry()方法,
- 其主要作用是筛选出当前项目环境需要启动的自动配置类XxxAutoConfiguration
- 从而实现当前项目运行所需的自动配置环境。
另外,在上述核心方法中加粗显示了2个重要的业务处理方法,具体说明如下。
- this.getCandidateConfigurations(annotationMetadata, attributes)方法: 该方法的主要作用是从Spring Boot提供的自动配置依赖的META-INF/spring.factories文件中 获取所有候选自动配置类XxxAutoConfiguration(2.1.3版本提供有121个自动配置类);
- this.filter(configurations, autoConfigurationMetadata)方法: 该方法的作用是对所有候选的自动配置类进行筛选,根据项目pom.xml文件中加入的依赖文件筛选出 最终符合当前项目运行环境对应的自动配置类(筛选完成后可能只有25个)。
SpringBoot 提供的自动配置类
SpringBoot在启动的时候从自动配置类路径下的META-INF/spring.factorles中获取
EnableAutoConfiguration指定的值,并将这些值作为自动配置类导入到容器中,自动配置类就生效。
在项目中加入了Web环境依赖启动器
- 对应的WebMvcAutoConfiguration自动配置类就会生效,打开该自动配置类会发现 在该配置类中通过全注解配置类的方式对Spring MVC运行所需环境进行了默认配置, 包括:默认前缀、默认后缀、视图解析器、MVC校验器等。
- 而这些自动配置类的本质是传统Spring MVC框架中对应的XML配置文件
- 只不过在Spring Boot中以自动配置类的形式进行了预先配置。
- 因此,在Spring Boot项目中加入相关依赖启动器后,基本上不需要任何配置就可以运行程序,
- 当然,我们也可以对这些自动配置类中默认的配置进行更改。
@ComponentScan注解
@ComponentScan注解是一个组件包扫描器,
其主要作用是扫描指定包及其子包下所有注解类文件作为Spring容器的组件使用。
okok, 就到这里了, 后面在深入研究~ 好累需要反复斟酌~
Spring常用注解使用分析:
@Configuration
相当于 Spring配置文件中的< beans>标签
告诉SpringBoot这是一个配置类,配置类本身也是组件 等于以前Spring项目的Sring配置文件.xml;
配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的 Full
另外注意,**被@configuration标注的类本身,也会作为一个bean注入到容器中的。
**
Full模式与Lite模式
proxyBeanMethods:代理bean的方法
- Full(proxyBeanMethods = true) 保证每个@Bean方法被调用多少次返回的组件都是单实例的
- Lite(proxyBeanMethods = false) 每个@Bean方法被调用多少次返回的组件都是新创建的
- 组件依赖必须使用Full模式默认。
@Bean
给容器中添加组件。
以方法名作为组件的 id。返回类型就是组件类型。返回的值,就是组件在容器中的实例;
Demo测试1
以上项目加一个包 com.wsm.entity
加一个 测试实体类 User.Java
public class User {
private int id=0;
private String name="默认";
//get/set
//toString()....
加一个包 com.wsm.config
加入一个 配置类
ConfigXX.Java
//配置类学习
@Configuration
public class ConfigXX {
//Bean
//就相当于以前的: <Bean></Bean>
@Bean //以方法名作为组件的id 返回类型就是组件类型。返回的值,就是组件在容器中的实例
public String str(){
return "字符";
}
@Bean("myUser") //指定组件id名,将该对象存储到spring的上下文中 (环境中)
public User user() {
User user = new User();
user.setId(1);
user.setName("张三");
return user;
}
@Bean("tom")
public User userTom(){
User user = new User();
user.setId(1);
user.setName("tom");
return user;
}
}
主程序类SpringBootRun.Java
@SpringBootApplication //标注主程序类,这是一个Springboot应用!
public class SpringBootRun {
public static void main(String[] args) {
//用来执行开启SpringBoot程序; 参数当前主程序类.class args
ConfigurableApplicationContext run = SpringApplication.run(SpringBootRun.class,args);
//查看容器里面所有的组件,Bean
String[] names = run.getBeanDefinitionNames();
System.out.println("-----------所有的组件Bean----------");
for (String name : names) {
//因为,有很多是默认的所以会有很多~
System.out.println(name);
}
//从容器中根据id获取指定组件
String str = (String)run.getBean("str"); //方法返回Object类型——》强制转换
System.out.println(str);
//查询Spring上下文存在该元素
boolean isok = run.containsBean("str");
System.out.println(isok);
User myUser = (User)run.getBean("myUser");
System.out.println(myUser);
User tom1 = (User)run.getBean("tom");
User tom2 = (User)run.getBean("tom");
System.out.println(tom1==tom2); //比较结果:true 结论@Configuration默认模式是Full 单例
//被@Configuration注解的类同时也被注入
ConfigXX cfx = (ConfigXX)run.getBean(ConfigXX.class);
System.out.println(cfx.user()==cfx.user()); //结果为true 调用new 的方法同样是true;
}
}
@ImportResource 引入原生配置
以上的配置类 的使用, 刚开始学习时候有一点的不舒服~
SpringBoot 本质上是Spring的管理, 当然还是支持Spring的核心 IOC
也还可以使用以前的Spring配置文件来管理项目!
- 使用 @ImportResource 引入原生配置
Demo测试2
Maven工程 resource资源目录下添加一个Sping配置文件:
beanConf.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="w" class="com.wsm.entity.User"></bean>
</beans>
主程序
代码语言:javascript复制@SpringBootApplication //标注主程序类,这是一个Springboot应用!
@ImportResource("classpath:beanConf.xml") //classpath表示就是资源目录下; 这里不多解释了...
public class SpringBootRun {
public static void main(String[] args) {
//用来执行开启SpringBoot程序; 参数当前主程序类.class args
ConfigurableApplicationContext run = SpringApplication.run(SpringBootRun.class,args);
User user = (User) run.getBean("w");
System.out.println(user);
}
}
@import
声明在类上
这个注解在老版本SpringBoot1中,将他放在configuration 配置类上的时候
- 只能完成引入别的configuration类的功能。类似于容器xml配置文件的import标签。
但是在新版本中,可以引入任何类,不一定是configuration类。
- 这样就变得非常灵活。这里 的引入就是注入的意思。将该类注入到容器中,
- 即使该类没有被注解@service, @controller,@repository, @component等所标注。
语法:
@import({注入类.class,多个类.class})
主程序类
代码语言:javascript复制@SpringBootApplication //标注主程序类,这是一个Springboot应用!
@Import({User.class})
public class SpringBootRun {
public static void main(String[] args) {
//用来执行开启SpringBoot程序; 参数当前主程序类.class args
ConfigurableApplicationContext run = SpringApplication.run(SpringBootRun.class,args);
User u = run.getBean(User.class);
System.out.println(u);
}
}
注意:
使用前要确保该类型确实不存在任何一个Spring管理Bean
不然:
@componentscan
这个注解主要是标注需要扫描哪些包路径。
该路径下标注了@service, @controller,@repository, @component的类,
都将被注入到容器中。除了这四个标签,包路径下标注了@configuration类,也会被注入到容器中。
@import 升级版本!
@Conditional 条件装配
声明在 配置类上!**@Configuration
**
只有满足Conditional指定的条件,则进行 配置类组件注入!!!
实现动态配置 SpringBoot 的组件, 对一些组件进行判断则生成~
- SpringBoot 底层配置了这么多的类不可能每次都全部加载!!
- 底层就是采用该注解进行配置,是否存在使用依赖则执行底层类的注入
大致原理有兴趣在研究
~ - 该注解的类型有很多…
Demo3测试3
修改ConfigXX.Java
@Configuration
@ConditionalOnBean(name = "abc") //检查上下文中是否存在abc,如果存在,才执行下面的所有的创建操作
//@ConditionalOnMissingBean(name = "abc")
//检查上下文中是否存在abc,如果没有存在,执行下面的所有的创建操作
public class ConfigXX {
//Bean
//就相当于以前的: <Bean></Bean>
@Bean //以方法名作为组件的id 返回类型就是组件类型。返回的值,就是组件在容器中的实例
public String str(){
return "字符";
}
@Bean("tom")
public User userTom(){
User user = new User();
user.setId(1);
user.setName("tom");
return user;
}
@Bean("myUser") //指定组件id名,将该对象存储到spring的上下文中 (环境中)
public User user() {
User user = new User();
user.setId(1);
user.setName("张三");
return user;
}
}
分别执行主程序:
代码语言:javascript复制@SpringBootApplication
public class SpringBootRun {
public static void main(String[] args) {
//用来执行开启SpringBoot程序; 参数当前主程序类.class args
ConfigurableApplicationContext run = SpringApplication.run(SpringBootRun.class,args);
//查看容器里面所有的组件,Bean
String[] names = run.getBeanDefinitionNames();
System.out.println("-----------所有的组件Bean----------");
for (String name : names) {
//因为,有很多是默认的所以会有很多~
System.out.println(name);
}
}
}
@ConditionalOnBean(name = “abc”) 存在执行
@ConditionalOnMissingBean(name = “tom”) 不存在执行
@ConfigurationProperties 配置绑定
在编写项目代码时,我们要求更灵活的配置,更好的模块化整合。
- 在 Spring Boot 项目中,为满足以上要求,
- 我们将大量的参数配置在
application.properties
或application.yml
文件中, - 通过 @ConfigurationProperties 注解,我们可以方便的获取这些参数值
application.properties和application.yml文件的区别
一般上来说,当我们创建一个SpringBoot项目时
,IDE会默认帮我们创建一个application.properties配置文件。有些朋友习惯把.properties文件改成.yml文件。
- .properties文件,通过.来连接,通过=来赋值,结构上,没有分层的感觉,但比较直接。
- .yml文件,通过:来分层,结构上,有比较明显的层次感,最后key赋值的:后需要留一个空格。
- 执行顺序: 如果工程中同时存在application.properties文件和 application.yml文件 yml文件会先加载,而后加载的properties文件会覆盖yml文件。 所以建议工程中,只使用其中一种类型的文件即可。
@Component
声明在 @ConfigurationProperties 类上
@Component (把普通pojo实例化到spring容器中,相当于配置文件中的 ) 泛指各种组件,
就是说当我们的类不属于各种归类的时候 (不属于@Controller、@Services等的时候)
我们就可以使用@Component来标注这个类。
@EnableConfigurationProperties
@EnableConfigurationProperties注解的作用是: 使用 @ConfigurationProperties 注解的类生效。
- 如果一个配置类只配置@ConfigurationProperties注解,而没有使用@Component 那么在IOC容器中是获取不到properties 配置文件转化的bean。
- 说白了 @EnableConfigurationProperties 相当于把使用 @ConfigurationProperties 的类进行了一次注入。
- @EnableConfigurationProperties 和 @Component
二者取其一
Demo测试.properties
com.wsm.entity包下加入 Student.Java
//配置类注解,被自动扫描发现
//@Component
@ConfigurationProperties(prefix = "stu") //指明前缀
@PropertySource("classpath:application.properties") //指明配置源文件位置
public class Student {
private int id;
private String name;
//get/set/toString()....
}
resources目录下加入application.properties
# 修改SpringBoot的端口 默认8080
server.port=9090
#根据@ConfigurationProperties 声明类的前缀进行 .属性=值 注入;
stu.id=10001
stu.name=admin
#.properties文件
#键值注入 字符串不需要引号..
主程序:
代码语言:javascript复制@SpringBootApplication
@EnableConfigurationProperties({Student.class})
public class SpringBootRun {
public static void main(String[] args) {
//用来执行开启SpringBoot程序; 参数当前主程序类.class args
ConfigurableApplicationContext run = SpringApplication.run(SpringBootRun.class,args);
Student stu = run.getBean(Student.class);
System.out.println(stu);
}
}
Demo测试.yml
com.wsm.entity包下加入 Person.java
@ConfigurationProperties(prefix = "person")
public class Person {
private String userName;
private Boolean boss;
private Date birth;
private Integer age;
private User user;
private String[] interests;
private List<String> animal;
private Map<String, Object> score;
private Set<Double> salarys;
//get/set/toString()
}
yml编写规范 学习
大小写敏感 使用缩进表示层级关系 缩进时不允许使用Tab键,只允许使用空格。 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可 YAML 支持的数据结构有三种
- 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
- 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
- 纯量(scalars):单个的、不可再分的值
一组键值对,使用冒号结构表示
键:值
:冒号后面必须跟着空格!! 一定要注意错误了不易检查!!
resources目录下加入application.yml
person:
userName: 张三
boss: true
birth: 2020/01/01 15:20:30
age: 20
user: #对象User类型
id: 1001
name: 张三
interests: ['test01','test02'] #字符串数组
animal: #字符串集合
- cat #字符串值
- dog
score: #Map类型 String,Object类型
english: #Map元素键1
first: 100 #Map键1的值:又是一个Map类型
last: 20
math: [10,20,30,40] #Map元素键2:也是一个Map类型
chinese: {one: 50,two: 60,three: 70}
salarys: [4555.5,4666.5,4777.5]
主程序:
代码语言:javascript复制@SpringBootApplication
@EnableConfigurationProperties({Student.class, Person.class})
public class SpringBootRun {
public static void main(String[] args) {
//用来执行开启SpringBoot程序; 参数当前主程序类.class args
ConfigurableApplicationContext run = SpringApplication.run(SpringBootRun.class,args);
Person person = run.getBean(Person.class);
System.out.println(person);
}
}
自动配置原理入门自定义
自动配置类的作用,配置注入功能组件自动完成。
根据上面的 SpringBoot的特定得知SpringBoot的底层就是大量的 自动配置类 SpringBoot2 128个
详情查看 @EnableAutoConfiguration注解
自定义 自动配置
pom.xml
<!-- 加入依赖 -->
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>SpringBoot128</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
</dependencies>
</project>
Spring Boot优化了很多配置的方式方法,
让我们少去了很多配置的环节。但又给了我们自定义配置的选择权。
在SpringBoot中会有许多的自带自动装配,
通常在启动时加载,如何实现自己定义的自动装配?我们需要三个 关键类:
属性读取类
该类的作用是读取hello开头的属性配置文件
读取值后会存入到容器中。默认值是Spring Boot
HelloProperties.Java
@Component
@ConfigurationProperties(prefix = "hello") //使用配置绑定 前缀hello
public class HelloProperties {
private String msg = "SpringBoot";
//默认值 SpringBoot,如果引入自动配置的项目可以通过 .properties .yml 文件中,进行更改!
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
核心事件类
该类主要处理 配置类要执行的主要功能!!
我们定义该类来将定义的msg加上hello前缀。
Hello.Java
public class Hello {
private String msg;
public String say(){
return "hello" getMsg(); //打印输出Hello msg
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
整合类
整合类是最重要的类,它关系着前两个类的运作。
HelloAutoConfigration.Java
@Configuration //这是一个配置类
@ConditionalOnClass(Hello.class) //是否存在 Hello的类,没有不执行类中操作...
@EnableConfigurationProperties(HelloProperties.class) //开启使用 @ConfigurationProperties 注解的类生效。
@ConditionalOnProperty(prefix = "hello", value = "enabled", matchIfMissing = true)
//prefix 数组,获取property名称的前缀,可有可无
//name 数组,property完整名称或部分名称,与prefix组合使用组成完整属性名称,与value不可同时存在
//value 数组,获取property完整名称或部分名称,与prefix组合使用成完整属性名称,与name不可同时存在
//havingValue 比较获取的属性值与havingValue给定的值是否相同,相同才加载配置类
//matchIfMissing 缺少property时是否加载,如果为true,没有该property属性也会正常加载,反之报错。
//是否存在 hello 属性则执行下面操作..
public class HelloAutoConfigration {
@Autowired
private HelloProperties helloProperties;
@Bean
@ConditionalOnMissingBean
public Hello createHello() {
Hello hello = new Hello();
hello.setMsg(helloProperties.getMsg());
return hello;
}
}
使用
将maven文件打包后加载入仓库
给要使用的类添加pom配置
在控制器输出
Controller
HelloController.Java
import com.wsm.Hello; //引入依赖的类型;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController //@Controller @ResponseBody
public class HelloController {
@Autowired
private Hello hello; //注入
@GetMapping(value = "/showMsg")
public String shoMsg(){
return hello.say();
}
}
引入自定义配置依赖
pom.xml
<!-- 引入自定义配置依赖 -->
<dependency>
<groupId>org.example</groupId>
<artifactId>SpringBoot128</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>