文章目录
前言
Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。
依赖管理
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.7.RELEASE</version>
</dependency>
<properties>
<activemq.version>5.15.14</activemq.version>
...
</properties>
引入springboot依赖,dependencies里声明了一些官方推荐的其他依赖及版本
从而导入这些依赖则不需要写版本
场景启动器:spring-boot-starter-xxx,或者其他开发者的 xxx-spring-boot-starter
会自动引入该场景基本依赖,按需加载。
开发者无需关注版本号,如需修改可以
<properties>
<mysql.version>5.1.43</mysql.version>
</properties>
可以设置idea里springboot初始化为阿里:https://start.aliyun.com
自动配置
- 自动配好Tomcat。
- 自动配好SpringMVC。
- 配好了web开发的字符等常见问题。
- 默认配置扫描注册主程序及其层级包。
- 各种配置有默认值。
- 按需加载各种starter场景。
自动装配的一些注解
/*proxyBeanMethods:代理bean的方法
Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
组件依赖必须使用Full模式默认。其他默认是否Lite模式*/
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
@ImportResource("classpath:beans.xml") //引入xml的配置文件。
@EnableConfigurationProperties({CacheProperties.class})//配置绑定该类
@ConfigurationProperties(prefix = "spring.cache")
//该类再绑定application.properties里以spring.cache为前缀的配置值。
@ConditionalXXX//条件装配,当满足一定条件才注入该组件
@ConditionalOnClass({CacheManager.class})
@ConditionalOnBean({CacheAspectSupport.class})
@ConditionalOnMissingBean(
value = {CacheManager.class},
name = {"cacheResolver"}
)
@ConfigurationProperties和yml配合,
相较于@Value,给属性注入值十分便捷。
@Data
@Component
@ConfigurationProperties(prefix = "user")
public class User {
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
}
user:
name: 用户
age: 1
happy: true
birth: 2021/2/21
maps: {k1:v1,k2:v2}
lists:
- code
- music
- girl
通过查看各种JavaConfig,可以找到对应配置项。
这样在配置文件里,相关配置则是spring.data.web.xxx。
在配置文件中配置debug: true可以在控制台输出配置类生效情况。
原理
• SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration。
• 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件进行了绑定。
• 生效的配置类就会给容器中装配很多组件。
• 只要容器中有这些组件,相当于这些功能就有了。
• 定制化配置。
• 用户直接自己@Bean替换底层的组件。
• 用户去看这个组件是获取的配置文件什么值就去修改。
多环境配置
spring.profiles.active=dev
Web开发
静态资源目录
通过阅读源码:WebMvcAutoConfiguration
called /static (or /public or /resources or /META-INF/resources
访问 : 当前项目根路径/ + 静态资源名
原理: 静态映射/**。
请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面
欢迎页
所以在静态资源里建立index.html即为欢迎页。
网页小图标
将图片改名favicon.ico 并放在静态资源目录下。
banner.txt
springboot启动图案。
404页面
templatest:下建一个error文件夹
error:
404.html.
4xx.html
5xx.html
模板引擎
thymeleaf:类似jsp。需要导包,页面都写在templates下,且只能controller访问。
通过springboot特性,寻找properties默认配置可以得到。
JSR303校验
@NotNull(message = "修改必须指定品牌id",groups = {UpdateGroup.class})
@Null(message = "新增不能指定id",groups = {AddGroup.class})
private Long brandId;
public R save(@Validated({AddGroup.class}) @RequestBody BrandEntity brand){}
rest风格
@RequestMapping(value = "/user",method = RequestMethod.GET)
@RequestMapping(value = "/user",method = RequestMethod.POST)
//put和delete需要post+表单携带一个_method=put的属性值
@RequestMapping(value = "/user",method = RequestMethod.PUT)
@RequestMapping(value = "/user",method = RequestMethod.DELETE)
参数注解
//路径变量car/2/owner/zhangsan
@GetMapping("/car/{id}/owner/{username}")
public Map<String,Object> getCar(@PathVariable("id") Integer id,//获取路径变量
//获取路径变量 @PathVariable("username") String name,
//Map可以接收所有参数 @PathVariable Map<String,String> pv,
//请求头 @RequestHeader("User-Agent") String userAgent,
@RequestHeader Map<String,String> header,
//请求参数 @RequestParam("age") Integer age,
//post请求体 @RequestBody("inters") List<String> inters,
@RequestParam Map<String,String> params,
//request.set @RequestAttribute("_ga") String _ga,
//cookie @CookieValue("_ga") Cookie cookie){
}
mvc支持返回值
ModelAndView
Model
View
ResponseEntity
ResponseBodyEmitter
StreamingResponseBody
HttpEntity
HttpHeaders
Callable
DeferredResult
ListenableFuture
CompletionStage
WebAsyncTask
有 @ModelAttribute 且为对象类型的
@ResponseBody 注解 —> RequestResponseBodyMethodProcessor;
扩展MVC配置
用于在默认mvc配置上,通过javaConfig增加一些自定义mvc配置: 路径映射、拦截器等。
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object loginUser = request.getSession().getAttribute("loginUser");
return loginUser!=null;
}
}
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/index.html").setViewName("index");
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/index.html","/","/user/login");
}
}
自定义的配置需要通过这个扩展,注册到mvc里。之前spring是用xml配置文件注册。
整合Druid
阿里的连接池,提供日志监控等功能。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.1</version>
</dependency>
spring:
datasource:
initialsize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
#配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
#如果允许报错,java.lang.ClassNotFoundException: org.apache.Log4j.Properity
#则导入log4j 依赖就行
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
@Configuration
public class DruidConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druidDataSource(){
return new DruidDataSource();
}
//相当于原生servlet
@Bean
public ServletRegistrationBean<StatViewServlet> statViewServlet(){
ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
Map<String,String> initParameters = new HashMap<>();
//设置登录密码
initParameters.put("loginUsername","admin");
initParameters.put("loginPassword","123456");
bean.setInitParameters(initParameters);
return bean;
}
}
整合Mybatis
<!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
按照springboot的配置方法,查看mybatis的配置类即可得到配置参数
mybatis.type-aliases-package=com.yaostudy.pojo
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
编写dao加上@Mapper注解即可实现和Spring中注册bean的效果。
也可以使用@MapperScan设置扫描包路径,
mybatis也如springboot一样,通过javaconfig方式注册sqlsessionfactory等,从而省去了配置文件。
整合Swagger
swagger是为了解决前后端分离时,前端后端关于接口的实时调试集成问题,通过使用swagger可以实时、便捷的生成一个在线的RestFul api接口文档。api与api文档同步更新。
swagger也可以测试。
导入依赖
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
配置
@Configuration
@EnableSwagger2
public class SwaggerConfig {
//分组,之后可以和微服务结合
@Bean
public Docket docket2(){
return new Docket(DocumentationType.SWAGGER_2).groupName("yao2");
}
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.groupName("yao")
.select()
//配置扫描包
//withClassAnnotation
//withMethodAnnotation
//.basePackage("com.yao.controller")
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
//过滤路径
//.paths(PathSelectors.ant(""))
.build();
}
private ApiInfo apiInfo(){
return new ApiInfo("我的api文档",
"文档描述",
"v1.0",
"www.baidu.com",
new Contact("yao", "www.baidu.com", "12345@qq.com"),
"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList<VendorExtension>());
}
}
@ApiModel("用户实体类")
@Data
public class User {
private int id;
@ApiModelProperty("用户名")
private String username;
@ApiModelProperty("密码")
private String password;
}
@RestController
@Api(tags = "hello控制器")
public class HelloController {
@ApiOperation("hello方法")
@PostMapping("/hello")
public String hello(@ApiParam("参数注解") String str){
return "hello";
}
//返回值存在实体类,则会扫把到model
@ApiOperation("model方法")
@GetMapping("/user")
public User user(){
return new User();
}
}
访问http://localhost:8080/swagger-ui.html即可
在正式发布的时候,需要关闭swagger。
任务
异步任务
Spring自带
@Service
public class AsyncService {
//异步处理
@Async
public void hello(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("数据处理完毕");
}
}
@RestController
public class AsyncController {
@Autowired
private AsyncService asyncService;
@RequestMapping("/hello")
public String hello(){
asyncService.hello();
return "ok";
}
}
//开启异步
@EnableAsync
@SpringBootApplication
public class TaskApplication {}
前端直接输出ok,不用等待 数据处理完毕。
邮件任务
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
搜索MailProperties,找到配置项
spring.mail.username=123@qq.com
spring.mail.password=wmlpxsaxwmpidagj
spring.mail.host=smtp.qq.com
spring.mail.properties.mail.smtp.ssl.enable=true
@SpringBootTest
class TaskApplicationTests {
@Autowired
JavaMailSender MailSender;
@Test
void contextLoads() {
//简单邮件发送
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setSubject("主题");
mailMessage.setText("正文");
mailMessage.setTo("123@qq.com");
mailMessage.setFrom("123456@qq.com");
MailSender.send(mailMessage);
}
@Test
void contextLoads2() throws MessagingException {
//复杂邮件发送
MimeMessage mimeMessage = MailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);
helper.setSubject("主题");
helper.setText("<p style='color:red'>正文,true开启html标签</p>",true);
//附件
helper.addAttachment("文件.jpg",new File("C:\\Users\\yao\\Desktop\\f.jpg"));
helper.setTo("123@qq.com");
helper.setFrom("1233@qq.com");
MailSender.send(mimeMessage);
}
}
定时执行任务
spring自带异步定时任务。
@EnableScheduling
@SpringBootApplication
public class TaskApplication {}
@Service
public class ScheduledService {
//cron 表达式
//秒 分 时 日 月 周
@Scheduled(cron = "0 * * * * 0-7")
public void hello(){
System.out.println("执行");
}
}
启动后,每分种的0秒会执行。
cron表达式可以百度搜索。
总结
使用SpringBoot开发十分快捷方便,但是想要使用的更加明白一点,就需要结合spring和servlet,对于JavaConfig这种配置形式有一定的理解,这是springboot的核心autoconfig自动装配的关键所在。