springboot 学习 一

    xiaoxiao2023-10-15  138

    一、Spring Boot入门 1、Spring Boot简介 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。

    2、微服务 微服务:架构风格(服务微化)

    一个应用应该是一组小型服务,可以通过HTTP的方式进行互通

    单体应用:ALL IN ONE

    微服务:每个功能元素最终都是一个可以独立替换和升级的软件单元

    3、环境准备 环境约束

    jdk1.8 maven 3.x :maven3.3以上 IDEA2017 SpringBoot 1.5.9RELEASE 1、MAVEN设置

    jdk18 true 1.8

    nexus-aliyun 首选,放第一位,有不能下载的包,再去做其他镜像的选择

    nexus-aliyun central Nexus aliyun http://maven.aliyun.com/nexus/content/groups/public <!-- 备选镜像,也是可以通过 url 去查找确定一下, 该镜像是否含有你想要的包,它比 spring-libs-milestone 快 --> central-repository * typorCentral Repository http://central.maven.org/maven2/

    2、IDEA设置 ​ 配置IDEA的Maven,指定Setting的Maven目录和MAVEN的setting.xml文件

    ​ 快捷键:

    ​ Ctrl+D 复制一行

    ​ Ctrl+Y 删除一行

    ​ Ctrl+P 参数提示

    ​ Ctrl+Alt+V 自动补齐方法

    ​ Ctrl+N 查找类方法

    ​ Alt+Ins 构造器、getter/setter toString

    ​ Ctrl+O 重载方法提示

    ​ Alt+Enter 提示导入类etc

    ​ Shift+F6 :文件重命名

    4、Spring Boot的Hello World 1、创建一个Maven工程 2、导入Spring Boot的相关依赖

    <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.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> </dependencies>

    3、编写个主程序

    @SpringBootApplication public class SpringBoot01HelloQuickApplication { public static void main(String[] args) { SpringApplication.run(SpringBoot01HelloQuickApplication.class, args); } }

    4、编写相应的Controller和Service

    @Controller public class HelloController { @ResponseBody @RequestMapping("/hello") public String hello(){ return "hello world"; } }

    5、运行主程序测试 访问 localhost:8080/hello

    6、简化部署 在pom.xml文件中,导入build插件

    <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>

    5、HelloWorld深度理解 1.POM.xml文件 1、父项目

    <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.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.0.1.RELEASE</version> <relativePath>../../spring-boot-dependencies</relativePath> </parent>

    下面有个属性,定义了对应的版本号

    <properties> <activemq.version>5.15.3</activemq.version> <antlr2.version>2.7.7</antlr2.version> <appengine-sdk.version>1.9.63</appengine-sdk.version> <artemis.version>2.4.0</artemis.version> <aspectj.version>1.8.13</aspectj.version> <assertj.version>3.9.1</assertj.version> <atomikos.version>4.0.6</atomikos.version> <bitronix.version>2.1.4</bitronix.version> <build-helper-maven-plugin.version>3.0.0</build-helper-maven-plugin.version> 。。。。。。。

    Spring Boot的版本仲裁中心 会自动导入对应的版本,不需要我们自己导入依赖,没有dependencies里面管理的依赖自己声明

    2、启动器

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

    **spring-boot-starter-web:**帮我们导入web模块正常运行所依赖的组件

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

    2、主程序入口

    @SpringBootApplication public class SpringBoot01HelloQuickApplication { public static void main(String[] args) { SpringApplication.run(SpringBoot01HelloQuickApplication.class, args); } }

    @SpringBootApplication: 说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动应用

    进入SpringBootApplication注解

    @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 {

    @SpringBootConfiguration:SpringBoot的配置类: 标准在某个类上,表示这是一个SpringBoot的配置类

    @Configuration:配置类上,来标注这个注解; 配置类 ---- 配置文件,也是容器中的一个组件(@Component) @EnableAutoConfiguration:开启自动配置功能 以前需要自动配置的东西,Spring Boot帮我们自动配置;@EnableAutoConfiguration告诉SpringBoot开启自动 配置功能;这样自动配置才能生效。

    @AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { @AutoConfigurationPackage:自动配置包 @Import({Registrar.class}):底层注解,给容器导入组件; 将主配置类(@SpringBootApplication标注的类)的所在包及下面所有的子包里面的所有组件扫描到Spring容器;

    @Import({AutoConfigurationImportSelector.class}): 给容器导入组件?

    AutoConfigurationImportSelector:导入组件选择器

    将所有需要导入的组件以及全类名的方式返回;这些组件将以字符串数组 String[] 添加到容器中;

    会给容器非常多的自动配置类,(xxxAutoConfiguration);就是给容器中导入这个场景需要的所有组件,并配置 好这些组件。

    1.configuration 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; } SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());

    Spring Boot在启动的时候从类路径下的META-INF/spring.factorys中获取的EnableAutoConfiguration指定的值;

    将这些值作为自动配置类导入到容器中,自动配置就生效了。 2.factories

    J2EE的整体解决方案

    org\springframework\boot\spring-boot-autoconfigure\2.0.1.RELEASE\spring-boot-autoconfigure-2.0.1.RELEASE.jar

    6、使用Spring Initializer创建一个快速向导 1.IDE支持使用Spring Initializer

    自己选择需要的组件:例如web

    默认生成的SpringBoot项目

    主程序已经生成好了,我们只需要完成我们的逻辑

    resources文件夹目录结构

    static:保存所有的静态文件;js css images

    templates:保存所有的模板页面;(Spring Boot默认jar包使用嵌入式的Tomcat,默认不支持JSP);可

    以使用模板引擎(freemarker.thymeleaf);

    application.properties:Spring Boot的默认配置,例如 server.port=9000

    二、配置文件 1、配置文件 Spring Boot使用全局配置文件,配置文件名是固定的;

    application.properties application.yml 配置文件作用:修改Spring Boot在底层封装好的默认值;

    YAML(YAML AIN’T Markup Language)

    是一个标记语言

    又不是一个标记语言

    标记语言:

    以前的配置文件;大多数使用的是 xxx.xml文件;

    以数据为中心,比json、xml等更适合做配置文件

    YAML:配置例子

    server: port: 9000 XML:

    9000 2、YAML语法 1、基本语法 k:(空格)v:表示一堆键值对(空格必须有);

    以空格的缩进来控制层级关系;只要是左对齐的一列数据,都是同一层级的

    server: port: 9000 path: /hello 属性和值也是大小写敏感

    2、值的写法 字面量:普通的值(数字,字符串,布尔)

    k: v:字面直接来写;

    字符串默认不用加上单引号或者双引号

    “”:双引号 不会转义字符串里的特殊字符;特殊字符会作为本身想要表示的意思

    name:“zhangsan\n lisi” 输出:zhangsan换行 lisi

    ‘’:单引号 会转义特殊字符,特殊字符最终只是一个普通的字符串数据

    name:‘zhangsan\n lisi’ 输出:zhangsan\n lisi

    对象、Map(属性和值)键值对

    k :v :在下一行来写对象的属性和值的关系;注意空格控制缩进

    对象还是k:v的方式

    frends: lastName: zhangsan age: 20

    行内写法

    friends: {lastName: zhangsan,age: 18}

    数组(List、Set): 用-表示数组中的一个元素

    pets: ‐ cat ‐ dog ‐ pig

    行内写法

    pets: [cat,dog,pig]

    组合变量

    多个组合到一起

    3、配置文件值注入 1、@ConfigurationProperties 1、application.yml 配置文件

    person: age: 18 boss: false birth: 2017/12/12 maps: {k1: v1,k2: 12} lists: - lisi - zhaoliu dog: name: wangwang age: 2 last-name: wanghuahua

    application.properties 配置文件(二选一)

    idea配置文件utf-8 properties 默认GBK

    person.age=12 person.boss=false person.last-name=张三 person.maps.k1=v1 person.maps.k2=v2 person.lists=a,b,c person.dog.name=wanghuahu person.dog.age=15

    所以中文输出乱码,改进settings–>file encoding -->[property–>utf-8 ,勾选转成ascii]

    javaBean

    /**

    将配置文件的配置每个属性的值,映射到组件中@ConfigurationProperties:告诉SpringBoot将文本的所有属性和配置文件中的相关配置进行绑定;prefix = “person” 配置文件爱你的那个属性进行一一映射

    只有这个组件是容器中的组件,才能提供到容器中 */

    @Component @ConfigurationProperties(prefix = "person") public class Person { private String lastName; private Integer age; private Boolean boss; private Map<String,Object> maps; private List<Object> lists; private Dog dog;

    导入配置文件处理器,以后编写配置就有提示了

    <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring‐boot‐configuration‐processor</artifactId> <optional>true</optional> </dependency>

    2、@Value注解 更改javaBean中的注解

    @Component public class Person { /** * <bean class="Person"> * <property name="lastName" value="字面量/${key}从环境变量/#{spEL}"></property> * </bean> */ @Value("${person.last-name}") private String lastName; @Value("#{11*2}") private Integer age; @Value("true") private Boolean boss; @ConfigurationProperties @Value

    功能 批量注入配置文件属性 单个指定 松散绑定(语法) 支持 不支持 spEL 不支持 支持 JSR303校验 支持 不支持 复杂类型 支持 不支持 松散语法:javaBean中last-name(或者lastName) -->application.properties中的last-name;

    spEL语法:#{11*2}

    JSR303:@Value会直接忽略,校验规则

    JSR303校验:

    @Component @ConfigurationProperties(prefix = "person") @Validated public class Person { @Email private String lastName;

    复杂类型栗子:

    @Component public class Person { /** * <bean class="Person"> * <property name="lastName" value="字面量/${key}从环境变量/#{spEL}"></property> * </bean> */ private String lastName; private Integer age; private Boolean boss; // @Value("${person.maps}") private Map<String,Object> maps;

    以上会报错,不支持复杂类型

    使用场景分析

    ​ 如果说,我们只是在某个业务逻辑中获取一下配置文件的某一项值,使用@Value;

    如果专门编写了一个javaBean和配置文件进行映射,我们直接使用@ConfigurationProperties

    举栗子:

    1、编写新的Controller文件

    @RestController public class HelloController { @Value("${person.last-name}") private String name; @RequestMapping("/hello") public String sayHello(){ return "Hello"+ name; } }

    2、配置文件

    person.age=12 person.boss=false person.last-name=李四 person.maps.k1=v1 person.maps.k2=v2 person.lists=a,b,c person.dog.name=wanghuahu person.dog.age=15

    3、测试运行

    访问 localhost:9000/hello

    结果为Hello 李四

    3、其他注解 @PropertySource

    作用:加载指定的properties配置文件

    1、新建一个person.properties文件

    person.age=12 person.boss=false person.last-name=李四 person.maps.k1=v1 person.maps.k2=v2 person.lists=a,b,c person.dog.name=wanghuahu person.dog.age=15

    2、在javaBean中加入@PropertySource注解

    @PropertySource(value = {"classpath:person.properties"}) @Component @ConfigurationProperties(prefix = "person") public class Person { private String lastName; @ImportResource

    作用:导入Spring配置文件,并且让这个配置文件生效

    1、新建一个Spring的配置文件,bean.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="HelloService" class="com.wdjr.springboot.service.HelloService"></bean> 2、编写测试类,检查容器是否加载Spring配置文件写的bean @Autowired ApplicationContext ioc; @Test public void testHelloService(){ boolean b = ioc.containsBean("HelloService"); System.out.println(b); } import org.springframework.context.ApplicationContext;

    3、运行检测

    结果为false,没有加载配置的内容

    4、使用@ImportResource注解

    将@ImportResource标注在主配置类上

    @ImportResource(locations={"classpath:beans.xml"}) @SpringBootApplication public class SpringBoot02ConfigApplication { public static void main(String[] args) { SpringApplication.run(SpringBoot02ConfigApplication.class, args); } }

    5、再次运行检测

    结果为true

    缺点:每次指定xml文件太麻烦

    SpringBoot推荐给容器添加组件的方式:

    1、配置类=====Spring的xml配置文件(old)

    2、全注解方式@Configuration+@Bean(new)

    4.MyAppConfig

    /**

    @Configuration:指明当前类是一个配置类;就是来代替之前的Spring配置文件

    在配置文件中用标签添加组件 */

    @Configuration public class MyAppConfig { //将方法的返回值添加到容器中;容器这个组件id就是方法名 @Bean public HelloService helloService01(){ System.out.println("配置类给容器添加了HelloService组件"); return new HelloService(); } } @Autowired ApplicationContext ioc; @Test public void testHelloService(){ boolean b = ioc.containsBean("helloService01"); System.out.println(b); }

    容器这个组件id就是方法名

    4、配置文件占位符 1、随机数 r a n d o m . v a l u e 、 {random.value} 、 random.value{random.int}、${random.long} r a n d o m . i n t ( 10 ) 、 {random.int(10)}、 random.int(10){random.int[100,200]} 2、获取配置值

    person.age=${random.int} person.boss=false person.last-name=张三${random.uuid} person.maps.k1=v1 person.maps.k2=v2 person.lists=a,b,c person.dog.name=${person.last-name}'s wanghuahu person.dog.age=15

    存在以下两种情况

    没有声明person.last-name会报错,新声明的需要加默认值

    person.age=${random.int} person.boss=false person.last-name=张三${random.uuid} person.maps.k1=v1 person.maps.k2=v2 person.lists=a,b,c person.dog.name=${person.hello:hello}'s wanghuahu person.dog.age=15

    结果:输出hello’s wanghuahua

    最新回复(0)