前言
大家好,一直以来我都本着 用最通俗的话理解核心的知识点, 我认为所有的难点都离不开 基础知识 的铺垫
适合人群
- 学完Java基础
- 想通过Java快速构建web应用程序
- 想学习或了解SpringBoot
大佬可以绕过 ~
背景
本节给大家讲讲 Java的SpringBoot框架, 之前我们学习的都是java的基础知识和底层提供的一些能力,我们日常工作都是在写接口。在我们在产品开发中,一般我们都会选择比较稳定的框架来帮我们加速开发,不会自己去造轮子,而在java众多框架中,spring框架表现的非常好,大部分公司都会首选它作为开发框架,而至今,大部分企业都是以springboot
来构建项目了~
情景回顾
距离上期更新至今已经有一段时间了,由于最近较忙,没有时间去更新,后边有空就会及时更新。上期我们实现了一个简单的hello world请求,为了使项目更加规范,我对目录做了一些修改,后续的实战教程中会一直沿用这个项目,代码也会不断更新。最近github可能会被墙,所以我把源码放到了国内gitee上
往期内容
项目源码(持续更新⭐️)
配置讲解
Banner配置
我们先从控制台说起,我们在运行的时候,控制台会进行一些初始化的操作,然后你还会看到Springboot
的Logo, 我想换掉这个logo怎么做呢?
我们只需要在resources
目录下新建一个banner.txt
就可以了,它会自定替换这个文本里的文案,给个全网都在使用的文案:
_ooOoo_ o8888888o 88" . "88 (| -_- |) O\ = /O ____/`---'\____ .' \\| |// `. / \\||| : |||// \ / _||||| -:- |||||- \ | | \\\ - /// | | | \_| ''\---/'' | | \ .-\__ `-` ___/-. / ___`. .' /--.--\ `. . __ ."" '< `.___\_<|>_/___.' >'"". | | : `- \`.;`\ _ /`;.`/ - ` : | | \ \ `-. \_ __\ /__ _/ .-` / / ======`-.____`-.___\_____/___.-`____.-'====== `=---=' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 佛祖保佑 永无BUG 博客地址: https://www.qiucheng.top 复制代码
然后我们重新Run
一下, 发现启动的时候文案就被替换了,其实它是由一个属性控制的,我们点开 SpringApplication
会发现
private Banner banner; 复制代码
我们也可以关闭它, 默认源码是显示的
private Banner.Mode bannerMode = Banner.Mode.CONSOLE; 复制代码
我们在启动类上加上就可以关闭了
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication app = new SpringApplication(Application.class); // 关闭 banner app.setBannerMode(Banner.Mode.OFF); app.run(args); } } 复制代码
Server 配置
全局配置文件默认都是在application.yml
里,前期我们就先从简单的配置入手,后边用到再讲
server: port: 8080 # 设置应用端口,默认是8080 tomcat: max-threads: 800 # 设置最大线程数 uri-encoding: UTF-8 servlet: # 这个是添加请求前缀 context-path: /api 复制代码
我们改完之后重启一下,发现原来的请求/hello
找不到了,变成了 /api/hello
,关于前缀的问题,其实还是挺重要的。如果我们细化到版本,我们可以在指定控制器类上加入@RequestMapping("/v1)
, 比如现在想要请求 /api/v1/hello
@RestController @RequestMapping("/v1") public class HelloController { @RequestMapping("/hello") public String hello(){ return "Hello World!"; } } 复制代码
自定义配置
如果我想在application.yml
里写入自定义配置怎么办?
app: name: ${spring.name} version: "1.0" 复制代码
在配置文件中可以使用 ${}
继承属性值,配置好了,怎么在代码中获取它们呢?使用 @Value("${xxx.xxx}")
@RestController @RequestMapping("/v1") public class HelloController { @Value("${app.name}") private String name; @Value("${app.version}") private String version; @RequestMapping("/hello") public String hello(){ return "Hello World!" + name + version; } } 复制代码
现在这么使用可以,如果我这个配置属性相当多怎么办,难不成一个个@Value
吗?显然不行,所以也提供了另一种全局配置,首先我们要修改一下我们的pom.xml
添加如下, 不然会报错
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> </dependency> 复制代码
添加一个Config
@ConfigurationProperties(prefix="app") # 设置前缀 public class AppConfig { public String getName() { return name; } public void setName(String name) { this.name = name; } public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } private String name; private String version; } 复制代码
修改启动类:
@EnableConfigurationProperties({AppConfig.class}) @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication app = new SpringApplication(Application.class); // 关闭 banner app.setBannerMode(Banner.Mode.OFF); app.run(args); } } 复制代码
获取它, 使用 @Autowired
注入Bean
, 这里也建议大家在创建对象的时候不要 new
了,尽量给Spring
容器来管理
@RestController @RequestMapping("/v1") public class HelloController { @Value("${app.name}") private String name; @Value("${app.version}") private String version; @Autowired private AppConfig appConfig; @RequestMapping("/hello") public String hello(){ return "Hello World!" + name + version; } @RequestMapping("/hello1") public String hello1(){ return "Hello World!" + appConfig.getName() + appConfig.getVersion(); } } 复制代码
关于 @Component & @Configuration & @Service
其实这三者都有共通性,从字面意思讲各尽其职,有更好的语义化,我们通常编写配置类会使用 @Configuration
, 编写业务类会使用,比如封装第三方工具类等。
@Service
, 编写容器类使用 @Component
, 它们都可以使用 @Autowired
自动注入Bean
, 下边给大家简单演示一下
@Component
@Component public class App { @Value("${app.name}") private String name; @Value("${app.version}") private String version; public String getName() { return name; } public String getVersion() { return version; } } 复制代码
@Configuration
@Component public class App { @Value("${app.name}") private String name; @Value("${app.version}") private String version; public String getName() { return name; } public String getVersion() { return version; } } 复制代码
@Service
这个用法稍微跟上边不大一样,通常作用到实现类上,我们规范一点,先定义一个接口
public interface HelloService { void hello(); } 复制代码
实现类:
@Service public class HelloServiceImpl implements HelloService { @Override public void hello() { System.out.println("hello service"); } } 复制代码
使用:
@RestController @RequestMapping("/v1") public class HelloController { @Value("${app.name}") private String name; @Value("${app.version}") private String version; @Autowired private AppConfig appConfig; @Autowired private HelloService HelloService; @RequestMapping("/hello") public String hello(){ return "Hello World!" + name + version; } @RequestMapping("/hello1") public String hello1(){ return "Hello World!" + appConfig.getName() + appConfig.getVersion(); } @RequestMapping("/hello2") public String hello2(){ HelloService.hello(); return "Hello World!"; } } 复制代码
以上三者通常作用于类上,那有没有作用在方法上的呢?
@Bean
@Bean
注解比 @Component
注解的自定义性更强,而且很多地方我们只能通过 @Bean 注解来注册 bean。比如当我们引用第三方库中的类需要装配到 Spring 容器时,只能通过 @Bean 来实现。这里以线程池为例
@Configuration public class ThreadPoolConfig { @Bean(name = "threadPoolTaskExecutor") public ThreadPoolTaskExecutor threadPoolTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(4); executor.setMaxPoolSize(16); executor.setQueueCapacity(80); executor.setKeepAliveSeconds(120); executor.setThreadNamePrefix("thread-pool-"); return executor; } } 复制代码
我们可以看出非常的灵活, 可以实现自定义的东西
@Resource
除了@Autowire
, 还有@Resource
也可以用来装配bean,都可以用于字段或setter方法
@Autowire
默认按类型装配,默认情况下必须要求依赖对象必须存在,如果要允许 null 值,可以设置它的 required 属性为 false@Resource
默认按名称装配,当找不到与名称匹配的 bean 时才按照类型进行装配。名称可以通过name
属性指定,如果没有指定name
属性,当注解写在字段上时,默认取字段名,当注解写在setter
方法上时,默认取属性名进行装配。@Autowire
和@Qualifier
配合使用效果和@Resource
一样
提到 @Qualifier
,那就给大家讲一下
@Qualifier
我们都知道接口它的实现可以是多个类,这就造成了如果是多个实现类,在使用@Autowire
的时候,我注入的是哪个实现呢?所以我们加上@Qualifier
可以告诉Spring容器
,我使用这个实现类,光说抽象,我们实现一下:
添加一个实现类:
@Service("Hello1ServiceImpl") public class Hello1ServiceImpl implements HelloService { @Override public void hello() { System.out.println("Hello1ServiceImpl"); } } 复制代码
修改控制器:
@RestController @RequestMapping("/v1") public class HelloController { @Autowired @Qualifier("Hello1ServiceImpl") private HelloService HelloService; @RequestMapping("/hello2") public String hello2(){ HelloService.hello(); return "Hello World!"; } } 复制代码
这样就可以准确执行我们指定的实现类了
结束语
本期到这里就结束了,建议大家多动手实现一下,下期给大家讲解springboot
的请求处理 ~ 如果觉得不错,点个赞呗 ~