SpringBoot
SpringBoot现在分为两个技术栈,第一个是常规的使用servletAPI的Web编程方式,第二种是使用Reactive方式的响应式编程,Reactive Stack可以使用很少的内存来实现复杂的功能,提升性能并压缩成本,是一种很好的新型方式
SpringBoot优点
- 创建一个完整的、独立的Spring应用
- 内嵌独立的Tomcat服务器,不需要再进行其他配置
- 自动处理依赖关系,不需要自己进行依赖管理
- 自动配置spring以及第三方功能
- 自动进行生产级别的健康监控
- 无代码生成,不会因为一次一次的运行添加过多的代码
SpringBoot特点就是使用微服务构建出一个个的独立的模块,再用这些独立出来的模块进行分布式开发,分布式所涉及的问题可以由Spring Cloud进行解决,而产生的数据流也可以使用Spring Cloud Data Flow处理
使用SpringBoot的一个Demo
- 需要先创建一个maven项目并在项目的pom.xml文件中声明父工程:
在pom.xml文件中:
需要联网并下载依赖文件
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.4.RELEASE</version></parent>
-
只需要导入web场景启动器依赖就可以,不用其他复杂依赖
这个依赖中包括日志、springmvc等所有需要的依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
- 进行主类启动器的编写:
/*** @SpringBootApplication注解* 用来标识这是一个SpringBoot应用* 这个类是一个固定写法,作为springboot启动器*/
@SpringBootApplication
public class MainApplication {//固定写法public static void main(String[] args) {//参数为这个类的Class对象SpringApplication.run(MainApplication.class);}
}
- 进行Controller层的编写
/*** @ResponseBody注解用于标识所有的Return值是写给浏览器的,而不是代表跳转*/
//@ResponseBody
//@Controller/*** @RestController注解代表@Controller注解与@ResponseBody注解的合体* 是需要同时用到两个注解时的简单写法*/
@RestController
public class HelloController {@RequestMapping("/Hello")public String handle01() {return "Hello SpringBoot2!";}
}
所有的SpringBoot的配置都集成在application.properties文件中
例如端口号的修改只需要在Application.properties中添加server.port=新端口号即可
server.port=8888
另外,在简化pom.xml文件中加入构建项目的依赖:
<!-- 这个构建加入之后,进行打包就可以在cmd环境下直接运行springboot的项目,tomcat被直接集成在项目中--><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
这样在cmd的 java -jar命令下就可以直接在cmd的环境下运行这个项目
注意:在springboot环境下,所有的项目都是由父工程springboot进行统一管理的。
若需要某些依赖固定一些版本的话,则需要在pom.xml文件中添加properties标签并加入对应依赖属性,例如mysql版本的改变
<properties><mysql.version>5.1.43</mysql.version>
</properties>
记得在springboot依赖中找到对应的依赖的key属性
springboot是基于主程序所在的包进行包扫描的,所有与主程序在同一个包下的注解都会被扫描,但也可以进行扩大,只要在@SpringBootApplication的scanBasePackages属性下声明好就可以将扫描的包路径扩大。
SpringBoot的自动配置也是按需加载的,不会把所有的配置都加载,而是会在配置了对应的启动配置之后才会生效。
SpringBoot的配置文件
@Configuration注解用来标识一个类为配置类,Spring会寻找这个注解并将这个注解下的类中的方法视作创建对象,例如IoC中,对于对象的依赖注入就可以下面这么写:
在boot文件夹下创建配置类的存放文件夹config并创建一个类:MyConfig.java
//@Configuration注解,用来标识一个类,作用是进行配置,让SpringBoot来进行扫描时以配置类的眼光来看这个类以及其下的方法
@Configuration
public class MyConfig {@Bean //进行注入的注解,标识一个方法表示这个方法的返回值作为要返回的对象,返回值类型作为要创建的对象类型,方法名作为对象的id属性public User user01() {return new User("ZhangGeGe", 18);}//或者在Bean注解中添加一个value,则组件名后面就叫这个value的属性值,不会再叫方法名了。@Bean("Tom")public Pet cat() {return new Pet("Tomcat");}
}
验证配置:
在主类中通过循环获取所有的组件名称后可以看到有user01和Tom出现
public static void main(String[] args) {//参数为这个类的Class对象ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class);//查看容器内组件String[] names = run.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}}
并且是通过单例模式进行创建,因此会相等:
//查看容器内组件String[] names = run.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}Pet tom = run.getBean("Tom", Pet.class);Pet tom1 = run.getBean("Tom", Pet.class);System.out.println("组件:" + (tom == tom1));
此外:@Configuration还有一个proxyBeanMethods属性:
该属性:
//proxyBeanMethods属性代表其是否使用代理,使用代理则其为单例模式,每一个类只有一个对象,false则在每次调用的时候都会新创建一个对象
@Configuration(proxyBeanMethods = true)
//从容器中获取对象User user = bean.user01();User user1 = bean.user01();System.out.println("是否是一个:" + (user == user1));
简而言之:
- 不需要组件之间有依赖关系,允许多个实例时使用Lite模式(proxyBeanMethods = false),关闭它就不会检查容器中是否已有
- 需要依赖关系时使用Full模式(proxyBeanMethods = true)
@Import
@Import注解用于标注组件,并向容器中注入对象,这种方式注入的对象组件名叫做全类名,且会与@Bean注解注入的方式注入不同的对象,也就是说在容器中会存在两个组件
//Import组件,其形参是一个Class型的数据,只要在其中声明了,就会在容器中创建对应的对象
@Import({User.class, DBHelper.class})
@Conditional
Conditional组件用来标注类或者方法,只有当Conditional组件中内容成立时才会执行其所标注的语句
例如ConditionalOnBean注解标注时,只有当容器中有某个组件,下面语句才生效
@ConditionalOnBean(name = "Tom")
再录入@ConditionalOnMissingBean就代表容器中没有某个组件时才令下面的语句生效
@ImportResource
若有之前的第三方插件使用配置文件的方式进行文件配置时,可以在Config类上添加@ImportResource注解来将配置文件中的对象注入到容器中。
@ImportResource("classpath:bean.xml")
之后在容器中进行操作时就可以使用run.getBean(String)方法来获取组件。
@ConfigurationProperties 配置绑定
SpringBoot还提供了在配置文件中进行容器中组件的属性配置功能,在配置文件中以xxx.属性的方式进行配置,并在类上标识@ConfigurationProperties注解以及@Component注解来保证其存在于容器中,就可以进行属性配置,例如:
Application.proprties:
mycar.brand=BYD
mycar.price=100000
要绑定的类:
@Component
//.前面的要相等
@ConfigurationProperties(prefix = "mycar")
public class Car {private String brand;private Integer price;
另外,也可以使用@EnableConfigurationProperties注解来将指定的类来注入容器中,这个注解可以视作在Car类上标注了@Component注解,将这个类的对象组件直接加入容器。
@EnableConfigurationProperties(Car.class)
注意就算用了Enable这个注解,@ConfigurationProperties(prefix = “mycar”)这个注解也还是要写。
源码解析
@SpringBootApplication注解:
该注解相当于三个注解合起来:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(“要扫描的包名”)
- @SpringBootConfiguration底层中是一个@Configuration注解,标注Main类也是一个配置类的组件,主要作用是将其标注为启动类
- @ComponentScan(“要扫描的包名”)指定要扫描的包的路径,指明哪些包需要扫描
- @EnableAutoConfiguration中又是由@AutoConfigurationPackage组成的,这个注解标注了组件的注册,注册的地址是Main类所在的路径,故而我们的组件是从Main所在的文件夹决定的。
另外,@EnableAutoConfiguration注解也由@Import注解组成,该注解决定了SpringBoot在启动时加载所有的自动配置类,但只有在对应的配置需要开启时(有对应的组件导入时)才开启。(默认全部开启装载,但按需配置)
若使用@Bean注解的方法有形参传入,则传入的形参会自动从容器中找
关于配置与Application.Properties的绑定
所有的配置都会有一个xxxxAutoConfiguration类,这个类都会有一个@EnableConfigurationProperties注解,这个注解决定了自动配置需要的类,而这个类上一般会有@ConfigurationProperties注解,这个注解的prefix属性就决定了我们要在Application.properties文件中配置的属性的开头是哪些