springboot笔记

0.对比

模板化的大量配置文件,不需要tomcat运行。遵循约定,简化配置

springboot只是进一步的升级,简化项目搭建和开发。引入依赖,几行配置

springboot 微框架 = springmvc 控制器+ spring core项目管理

  • spring存在父容器spring.xml,子容器springmvc.xml。springboot只有一个
  • 内嵌tomcat
  • 简化maven,自动配置spring springmvc,没有xml

约定:

  • 只有一个入口类 xxxxApplication.java,在所有子包目录之上; 需要main项目启动函数
  • 配置文件:根目录resources中application.yml | application.properties
image-20221216212408119

image-20221216202540351

1.快速开始

  1. 创建spring项目,勾选springweb 
    
    or
    
    创建maven项目
    继承父项目 便于维护版本
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
    </parent>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
       
    2. 配置文件变成小树叶

    3. ```java
    @SpringBootApplication 入口类,整个项目的总入口
    public class AdminApplication {

    public static void main(String[] args) {
    // 入口类对象,参数(可以动态设置参数,如端口等)
    SpringApplication.run(AdminApplication.class, args);
    }
    }
  2. 写一个@RestController

1
2
3
4
5
@SpringBootApplication
@SpringBootConfiguration 加载spring springmvc环境
@EnableAutoConfiguration 开启自动配置 自动配置核心注解,配置spring以及第三方环境
@ComponentScan 组件扫描 当前包以及子包
<context:component-scan base-package="com.kuang"/>

2.多配置文件

1
2
3
4
5
6
7
server:
port: 8081

# 规定走dev环境
spring:
profiles:
active: dev

多环境情况:application为公共的

​ application.yml application-test.yml application-dev.yml application-prod.yml

此外,以外部生产配置文件启动(包含数据库隐私等)

java -jar –spring.config.location = filepath xxx.jar

3.创建对象

springboot 微框架 = springmvc 控制器

​ + spring 管理项目对象

spring创建对象

  1. < bean >
  2. 注解实现创建对象,需要扫描@Componet ,只是名称不同,为了更好的理解
  • @Controller
  • @Service
  • @Repository

Springboot

  1. @configuration 定义配置类 相当于xml。

    ​ 里面@Bean ,用在方法上,返回值交给工厂。默认方法名是id(或者@bean(“beanid”))。 相当于< bean>

  2. 注解实现创建对象,启动时自动扫描了 指定名称: @Service(“helloImpl”) @Qualifier(value = “helloImpl”)

    • @Controller
    • @Service
    • @Repository

4.属性注入

和spring一样,但都通过注解实现。包含引用类型和基本类型

  1. @Value(“${user.name}”) @Value(“xiaoming”) 单个注入

    • 数组也可以直接注入,yml逗号隔开
    • maps: “{‘aa’:’你好’}” #{${maps}}
  2. 批量注入,用在类上, @ConfigurationProperties(“spring.datasource”)

    自动找spring.datasource里面的属性,按名称注入到类的属性中,需要提供set方法

@Autowired

5.JSP集成

引入依赖 tomcat-embed-jasper ,解析jsp

java同级的webapp文件夹

原来springmvc有视图解析器,现在是设置配置文件

1
2
3
4
5
spring:
mvc:
view:
prefix: /
suffix: .jsp

通过插件启动,以防idea找不到jsp

6.整合Mybatis

0.引入依赖

  • spring-boot-starter-web
  • mysql驱动 druid数据源
  • mybatis-spring-boot-starter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>

<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>

1.配置数据源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/challenge2?serverTimezon=UTC&userUnicode=true&characterEncoding=utf-8
username: root
password: 123456

等价
<!--使用spring数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf8"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</bean>

2.创建Factory,指定mapper文件的位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mybatis:
type-aliases-package: com.dhu.yarn.entity
mapper-locations: classpath:com.dhu.yarn/mapper/*.xml
# 下滑线转大写
configuration:
map-underscore-to-camel-case: true
等价
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--数据源-->
<property name="dataSource" ref="dataSource"></property>
<!--mapper-->
<property name="mapperLocations" value="classpath:com/kuang/mapper/*.xml"></property>
<!--绑定mybatis配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/> (可以不要)
</bean>

3.@MapperScan(“com.xun.dao”) 扫描Dao接口所在的包,同时创建bean 。可能爆红但不影响

or @Mapper一个一个创建添加,让mybatis找到,表示他是用来访问数据库的 ,对应Mapper接口。同时可以创建bean

​ @Repository只可以创建普通bean,所以只起标识作用。单独使用bean of type BookMapper that could not be found.

等价

1
2
3
4
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="org.mybatis.spring.sample.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>

不用配置开启事务,直接在serviceImpl上@Transactional

7.测试

1
2
3
4
5
6
7
8
9
@SpringBootTest
class Springboot2ApplicationTests {
@Test
void contextLoads() {
}
}

import org.junit.jupiter.api.Test 用在Spring Boot 2.2.X以后 JUnit 5
import org.junit.Test用在2.2.x之前 添加 @RunWith(SpringRunner.class) 否则注释将被忽略

@Autowired service 层 ,调试单个service函数很快

8.热部署

1
2
3
4
5
6
7
8
9
10
11
12
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<!--是否不能传递-->
<optional>true</optional>
</dependency>

2. 勾选Build project automatically 修改了就编译生成.class文件
3. ctrl+alt+s,进入设置,然后选择高级设置,在Compiler下勾选 Allow auto-make to restart even if developed application is currently running 自动加载新的class到jvm

ctrl s保存后,等待日志

9.日志

默认集成logback,和log4j作用一样

日志级别:

image-20221219112645808

rootLogger默认

image-20221219113216242
1
2
3
4
5
logging:
level:
root: info #如果修改为debug, 信息变多了
com.baizhi.mapper: debug # 把mapper层设置为debug,可以显示sql日志

1
2
3
4
5
6
7
8
// 每次都要生成
private static Logger logger = LoggerFactory.getLogger(当前类.class);
logger.info("12312") # 代替sout
logger.error("端口冲突,异常信息:{} {}", "第一个参数", "第二个参数");

注解实现
@Slf4j
log.info("测试log-------------------------");

10.小项目

密码要md5(不可逆)加密保存,登录时将将密码转换后进行对比。传统项目成功后存入session中

1
String newpassword = DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8))

出现业务错误时,抛出异常

controller除了返回到页面,还包含跳转到别的controlle,注意使用forward还是redirect。

​ 如添加完成员工接口后redirect到查询接口,查询完成后forward到显示界面

11.AOP

spring

1
2
3
4
5
6
附加操作 继承接口
public class Log implements MethodBeforeAdvice {
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("执行了"+method.getName()+"方法");
}
}
1
2
3
4
5
6
7
配置bean;配置切入点,组装切面
<bean id="logbefore" class="aop.Log"></bean>
<aop:config>
<!-- 切入点 execution:执行的位置 -->
<aop:pointcut id="pointcut" expression="execution(* com.kuang.service.UserserviceImpl.*(..))"></aop:pointcut>
<aop:advisor advice-ref="logbefore" pointcut-ref="pointcut"></aop:advisor>
</aop:config>

springboot

无xml文件

  1. 引入依赖

    1
    2
    3
    4
    5
    <!--aop日志-->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
  2. 编写切面类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Configuration  // spring配置类  spring.xml
@Aspect // 这个类是切面类 aop:config
public class MyAspectConfig {

// 切入点
@within("execution(com.xun.springboot2.controller.*)") //类级别
@Pointcut("execution(* com.xun.springboot2.controller.*.*(..))") //方法级别
public void controllerLog() {
}

// 切面 = 通知(Advice)+ 切入点(pointcut)
@Before("controllerLog()") @After 还可以针对注解生效
public void before(){
System.out.println("before");
}

@Around("controllerLog()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("around start");
Object proceed = proceedingJoinPoint.proceed(); // 需要返回方法中的数据
System.out.println("around end");
return proceed;
}
}

12.拦截器

spring:编写类,return true放行。然后注入bean并且配置拦截哪些请求

1
2
3
4
5
6
7
8
<!--拦截器注入-->
<mvc:interceptors>
<!--可以写多个拦截器-->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.kuang.config.JWTInterceptor"></bean> 或者分开 <ref bean = "beanname">
</mvc:interceptor >
</mvc:interceptors>

springboot

  1. 编写类,return true放行。// 多个拦截器是栈结构,pre1 pre2 do post2 post1
  2. 编写配置类,implements WebMvcConfigurer (原来写在springmvc.xml里,现在实现WebMvcConfigurer,WebMvcConfigurer里面包含很多mvc的配置方法,如addResourceHandlers)
    • 使用哪个拦截器
    • 拦截哪些
    • 排除哪些
1
2
3
4
5
6
7
8
9
10
11
12
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

public void addInterceptors(InterceptorRegistry registry){
registry.addInterceptor(new JWTInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/user/**")
.excludePathPatterns("/image/**")
.order(1) // 先执行
;
}
}

13.文件上传下载

上传到服务器本地、阿里云oss

打包成jar时,不能上传到项目内部的某个文件夹,因此直接上传到机器一个固定目录(配置文件注入)

本地和生产不同,使用多个配置文件

1
2
3
4
5
6
7
8
9
发送 multipart/form-data
接受 MultipartFile f


servlet:
multipart:
max-file-size: 300MB # 单个文件大小
max-request-size: 500MB # 设置总上传的数据大小
enabled: true #开启

下载

image-20221225202709373

14.异常处理

传统的:继承HandlerExceptionResolver,不同异常不同if处理

springboot:

1
2
3
4
5
6
7
8
9
@ControllerAdvice        // 默认监控全部controller
public class GlobalException {
@ExceptionHandler(BusinessException.class) // 处理哪个异常
@ResponseBody
public Result handleBusinessException(HttpServletRequest request, BusinessException ex) {
log.error(this.getClass()+"业务异常:"+ex.getMessage()+" 代码:"+ex.getCode());
return Result.error(ex.getCode(), ex.getMessage());
}
}

15.CORS

跨域资源共享

源:协议 域名 端口。默认情况下,不同源不能互相访问。ajax

controller类上@CrossOrigin 允许跨域访问

全局配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Configuration
public class CorsConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
// 1允许服务端访问
corsConfiguration.addAllowedOrigin("*");
// 2允许任何头
corsConfiguration.addAllowedHeader("*");
// 3允许任何方法(post、get等)
corsConfiguration.addAllowedMethod("*");
corsConfiguration.setMaxAge(600L);
// 4 允许withCredentials报文头
corsConfiguration.setAllowCredentials(true);
return corsConfiguration;
}

@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}
}

16.加密

jasypt对密码进行加密。提供一个类进行加密和解密,需要配置密钥,没有密钥解密会失败。在运行时传参输入密钥

使用:ENC(加密后字符串)

17.传参

参考sping里springmvc传参

18.restful

用访问方法指明操作,put要id和User,先查再改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserRepository userRepository;

@GetMapping("/")
public List<User> getAllUsers() {
}

@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable(value = "id") Long userId){
}

@PostMapping("/")
public User createUser(@RequestBody User user) {
}

@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable(value = "id") Long userId,
@RequestBody User userDetails) {
}

@DeleteMapping("/{id}")
public Map<String, Boolean> deleteUser(@PathVariable(value = "id") Long userId){
}
}