SpringBoot学习

程序 = 数据结构 + 算法 (程序员)

程序 = 面向对象 + 框架 (码农)

我们要学会ctrl+左键查看源码才能学习,而不是单纯去用

不断学习新知识(SpringBoot)

989a746364a84b8f997d16c6346954c9.png

 

jar包与war包?

jar包相当于是java代码的打包,而我们webapp运行时需要额外的东西,比如tomcat,如果打成jar包相当于把服务器内嵌了, 而war包更像是将java代码和相应额外的东西一起打包。

什么是spring?

@Component注解代表为spring的组件

Spring是为了解决企业级应用开发的复杂性而创建的,简化开发。 Spring就是作为容器去管理你的类,Spring管理的类在整个服务器启动期间在内存中只生成一份。 Spring的Ioc(控制反转和依赖注入) 控制反转:就是由容器控制程序之间的(依赖)关系,而非传统实现中,由程序代码直 接操控。 依赖注入:组件之间的依赖关系由容器在运行期决定 ,由容器动态的将某种依赖关系注 入到组件之中。通俗点说,例如A,B两个类都交由spring管理,A中有B的引用,那么在配置中可以事先配置好,服务器启动时初始化A的时候会自动将B注入到A中, 而不用再A中再次去用new来初始化B。spring还可以对事物进行管理。将hibernate的sessionFactory交由spring进行管理。她封装了所有对事务处理的功能, 包括异常时事务回滚,操作成功时数据提交等复杂业务功能。这都是由Spring容器来管理,大大减少了程序员的代码量,也对事务有了很好的管理控制。 1.sqlsession是mybatis用来将代码与数据库连接,包括执行sql语句,使用数据库执行相应操作,处理sql参数,结果集处理返回 2.service操作dao层,pojo对应数据库,通过配置文件嵌套来加载 3.配置上下文可以将配置文件关联在一起方便注入,也可以手动通过import resource引入 4.配置dao接口扫描包可以不用手写实现类 5.注解和配置文件都可以实现自动注入

spring如何简化开发?

1.基于POJO的轻量级和最小侵入性编程 2.通过IOC,依赖注入(DI)和面向接口实现松耦合 3.基于切面(AOP)和惯例进行声明式编程 4.通过切面和模板(比如jdbctemplate)减少样式代码

SpringBoot(约定大于配置)

简化javaweb开发

SpringBoot的配置文件 1.项目元数据信息:创建的时候输入的Project Metadata部分,也就是Maven项目的基本元素,包括:groupld,artifactld,version,name,description等 2.parent:继承spring-boot-starter-parent的依赖管理,控制版本与打包等内容,要用什么功能用启动器启动就行(启动器就是第一层的配置文件) 3.dependencies:项目具体依赖,这里包含了spring-boot-starter-web用于实现HTTP接口(该依赖中包含了Spring MVC),官网对它的描述是: 使用Spring MVC构建Web(包括RESTful)应用程序的入门者,使用tomcat作为默认嵌入式容器。;spring-boot-starter-test用于编写单元测试的依赖包。当然还有更多功能模块 4.build:构建配置部分。默认使用了spring-boot-maven-plugin,配合spring-boot-starter-parent就可以把Spring Boot应用打包成JAR来直接运行。

单体应用架构

将所有的应用服务封装到一个应用中,这样做方便开发和测试,需要扩展时也只用将war复制多份,然后放到多个服务器上进行负载均衡就行; 但是缺点也很明显,只要修改一个非常小的地方,就要停掉服务,重新打包,部署这个应用和war包,而且对于一个大型应用来说,把所有东西放在一个应用里面, 维护和合作都是问题。

微服务架构

打破之前all in one的结构方式,把每个功能元素独立出来。把独立出来的功能元素动态组合,需要的功能元素才用来组合,需要多一些时可以整合多个元素功能。 所以微服务架构是对功能元素进行复制,而没有对整个应用进行复制。 节省调用资源,每个功能元素的服务都是一个可替换的,可独立升级的软件代码。

cacc0840d06f45e9aecf22e5eeb52b03.png

 

SpringBoot的Application的注解

@SpringBootConfiguration(springboot的配置)
   @Configuration(spring的配置类)
      @Component(说明这是一个组件)
​
@EnableAutoConfiguration(自动配置类)
   @AutoConfigurationPackage(自动配置包)
      @Import({Registrar.class})(自动配置包注册)
   @Import({AutoConfigurationImportSelector.class})(自动配置导入选择)
      List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);(获取所有的配置)
​

获取所有的配置

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    List<String> configurations = new ArrayList(SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()));
    ImportCandidates.load(AutoConfiguration.class, this.getBeanClassLoader()).forEach(configurations::add);
    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories nor in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you are using a custom packaging, make sure that file is correct.");
    return configurations;
}

所以Application其实是将启动类下的所有资源导入,SpringBoot所有自动配置都是在启动的时候扫描并加载:spring-boot-autoconfigure的spring.factories有所有的自动配置类,但是不一定生效,要判断是否有对应的start(启动器)。

1.springboot在启动时,从类路径下/META-INF/spring.factories获取指定的值

2.将这些自动配置的类导入容器,自动配置就会生效

3.整合javaEE,解决方案和自动配置的东西都在spring-boot-autoconfigure这个包

4.它会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器

SpringApplication类

这个类主要做四件事

1.推断应用的类型是普通项目还是Web项目

2.查找并加载所有可用的初始化器,设置到initializers属性中

3.找出所有的应用程序监听器,设置到listeners属性中

4.推断并设置main方法的定义类,找到运行的主类

c30c23add24f4bf1867182c6e9fbadb8.png

 

Yaml

@PropertySource(value = "classpath:xxx.properties")可加载指定的不被spring扫描的配置文件,@Validated可进行JSR303数据校验

语法:properties只能保存键值对,但是yaml能存对象(并且对象通过@ConfigurationProperties(prefix = "对应的配置对象的名字,如下面的person")可以在配置文件里装配,不同于之前的属性上面写@Value,对象上面写@Autowired),数组,并且有行外和行内写法,{}代表对象,[]代表数组

properties:
name=ityz;
student.name=ityz;
student.age=18;
​
yaml: 
name: ityz(普通键值对);
student: {name: ityz,age: 18}或者
​
student:
  name: ityz
  age: ${random.int}(给随机值也行,这是spring的el表达式)
  happy: false
  birthday: 2002/07/29
  maps: {k1: v1,k2: v2}
  list:
     - code
     - girl
     - music
  dog:
     name: ${person.hello: hello}(占位符,如果没给值则默认为hello)_旺财
     age: 3  (对象); 
​
pets: [cat,dog,pig]或者
​
pets:
  - cat
  - dog (数组)`
​
​

配置文件识别优先级,工作中可以用多个配置文件来实现不同环境的测试

1.file:./config/
2.file:./
3.classpath:/config/
4.classpath:/
//classpath这里指的是resources目录,file指项目目录

Yaml还可以实现多文档模式,如下,以---间隔,以spring.profiles命名,以spring.profiles.active选择,如果用properties则需要多个文件,比如application-dev.properties。

server:
  port: 8081
spring:
  profiles:
    active: dev
  
---
server:
  port: 8082
spring:
  profiles: dev
  
  
---
server:
  port:  8083
spring:
  profiles: test

配置文件到底能写什么?

522f63c19ecf412eb625483a93ec29e6.jpeg

 

配置文件的固有规律:

xxxAutoConfiguration自动配置类帮我们自动装配东西,如果我们没有手动设置那就是默认值,而其中对应的xxxProperties由配置文件绑定,我们可以根据相应的名称去自定义值。就像之前的Application里面的注解,其实自动装配就是层层绑定。

首先我们要联系spring自动装配jar包的核心文件spring.factories所有组件来看,这里以HttpEncodingAutoConfiguration.java为例子

//表示这是一个配置类
@Configuration(proxyBeanMethods = false)
//自动配置绑定类的注解:HttpProperties可以点进去看绑定的配置
@EnableConfigurationProperties({HttpProperties})
//Spring底层注解:根据不同条件来判断当前配置是否生效
@ConditionalOnWebApplication(
    type = ConditionalOnWebApplication.Type.SERVLET
)
//字符编码过滤器
@ConditionalOnClass({CharacterEncodingFilter.class})
//判断是否存在配置,不存在就走默认
@ConditionalOnProperty(
    prefix = "spring.http.encoding",
    value = "enabled",
    matchIfMissing = true
)
​
//2.7版本以后的
@AutoConfiguration
@EnableConfigurationProperties({ServerProperties.class})
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@ConditionalOnClass({CharacterEncodingFilter.class})
@ConditionalOnProperty(
    prefix = "server.servlet.encoding",
    value = {"enabled"},
    matchIfMissing = true
)

可以通过配置文件中debug: true判断来查看哪些自动配置类生效,哪些没有生效

Spring Boot 2.7 新特性

自动配置变更(重要)

自动配置注册有了一个比较大的调整,之前都是写在下面 文件中的:

META-INF/spring.factories

现在改名了:

META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

0ef6e8f2ace340eba3158fbdf818e28d.png 

转存失败重新上传取消

另外格式也变了,Spring Boot 2.7 中直接每一行是一个自动配置类:

3c13c2c03f5947be841c37324a9a4b55.png

转存失败重新上传取消

编写格式确实是比之前方便多了,但文件名确实也太长了,比较难记。。。

需要注意的是:

为了向后兼容,META-INF/spring.factories 虽然现在被标识废弃了,但现在仍然可以使用,后续可能被彻底删除,建议使用新的规范。

Spring Boot 基础就不介绍了,推荐下这个实战教程:

https://github.com/javastacks...

新注解(@AutoConfiguration)

新增了一个自动配置注解 @AutoConfiguration,用来代替之前的 @Configuration,用于标识新自动配置注册文件中的顶级自动配置类,由 @AutoConfiguration 注解嵌套、导入进来的其他配置类可以继续使用 @Configuration 注解。

另外,为方便起见,@AutoConfiguration 注解还支持 after, afterNames, beforebeforeNames 属性进行自动配置排序,用于代替之前的 @AutoConfigureAfter@AutoConfigureBefore 注解。

这个注解可以说更加细分了吧,自动配置专用注解,用专门的注解来干专门的事,这样也可以用来区分用 @Configuration 标识的普通配置类。

静态资源

public void addResourceHandlers(ResourceHandlerRegistry registry) {
            if (!this.resourceProperties.isAddMappings()) {
                logger.debug("Default resource handling disabled");
            } else {
                this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");(可以读取webjars)
                this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
                    registration.addResourceLocations(this.resourceProperties.getStaticLocations());
                    if (this.servletContext != null) {
                        ServletContextResource resource = new ServletContextResource(this.servletContext, "/");
                        registration.addResourceLocations(new Resource[]{resource});
                    }
​
                });
            }
        }
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};(这些目录下的静态资源都能读取,也是按优先级读取的)
@ConfigurationProperties(
    prefix = "spring.mvc"
)
public class WebMvcProperties {
    private String staticPathPattern = "/**";(代表可以自己绑定属性修改读取路径)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值