一直使用springboot的部分功能,但是对springboot的理解还是不够全面的,期望能够有个全面的认知
本次读书笔记书籍:https://gitee.com/dalaoyang/springboot_book
https://item.jd.com/12663734.html?dist=jd
1 为什么使用springboot
快速,方便配置,的工具强大
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2 spring的基础功能
web项目
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello world";
}
}
webflux 异步的响应式编程Reactive Stream
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
</dependencies>
- 配置路由
- 配置方法
public Mono<ServerResponse> hello(ServerRequest request){
return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromObject("Hello, This is a SpringBoot WebFlux Project !"));
}
热启动
···
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
···
支持自定义属性通过@Value("${属性名}")
支持配置的来源和前缀
@PropertySource(value = "classpath:test.properties")
@ConfigurationProperties(prefix = "com.book")
支持多配置,通过active指定
···
spring.profiles.active=test
···
支持面板
- thymeleaf
- freemarker
- 使用jsp
模板定义
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
模板
th:text="${msg}"
jsp支持
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
bootstrap和jquery
···
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7-1</version>
</dependency>
<!-- 引用jquery -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.1.1</version>
</dependency>
···
国际化,使用国际化的拦截器
···
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver slr = new SessionLocaleResolver();
// 默认使用的语言
slr.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
return slr;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
// 参数名 用于区别使用语言类型
lci.setParamName("lang");
return lci;
}
···
上传或者下载
···java
上传文件
@RequestParam("file") MultipartFile file
写入文件file.transferTo(dest);
批量上传
List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");
下载文件
response.setContentType("application/force-download");// 设置强制下载不打开
response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 设置文件名
···
3 操作数据库
springboot支持的数据库
- mysql,sql server,oracle
- mongodb,neo4j,redis,memcached
支持jdbc
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
#insert
jdbcTemplate.update(sql);
#update
jdbcTemplate.update("UPDATE USER SET USER_PASSWORD = ? WHERE ID = ?",passWord,id);
#batch
jdbcTemplate.batchUpdate(sql,paramList);
#delete
jdbcTemplate.update("DELETE FROM ad WHERE ID = ?",id)
#query get list and one
jdbcTemplate.query(sql,new Object[]{name},new BeanPropertyRowMapper<>(Ad.class));
jdbcTemplate.queryForObject(sql,new Object[]{id},new BeanPropertyRowMapper<>(User.class));
jpa
<!-- JPA依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
jpa的实体已经包含了各种操作,不必特殊处理了
jpa基础操作
public interface UserRepository extends JpaRepository<User,Long> {
@Query("SELECT u FROM User u WHERE userName = :userName")
List<User> findAllByUserName(@Param("userName") String userName);
}
最新的mysql驱动
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
<scope>runtime</scope>
</dependency>
mybatis 支持3中方式
* xml
* 接口注解写sql
* sqlProvider模式
@SelectProvider(type = UserSqlProvider.class,method = "getSql")
##检查 mybatis 配置是否存在,一般命名为 mybatis-config.xml
mybatis.check-config-location =true
##配置文件位置
mybatis.config-location=classpath:mybatis/mybatis-config.xml
## mapper xml 文件地址
mybatis.mapper-locations=classpath*:mapper/*Mapper.xml
##日志级别
logging.level.com.springboot.dao.UserMapper=debug
mybatis支持生成map的xml文件
分页插件
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
mybatis-plus插件
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>xxx</version>
</dependency>
多数据源:为什么要多数据源?垂直和水平分库分表。逻辑清晰,减少数据库压力
jpa多数据源
- 多个DataSource,EntityManager,LocalContainerEntityManagerFactoryBean,PlatformTransactionManager
mybatis多数据源
- 多个datasource,SqlSessionFactory,DataSourceTransactionManager,SqlSessionTemplate
@Configuration
@MapperScan(basePackages = "xxx.datasource",
sqlSessionTemplateRef = "sqlSessionTemplatePrimary")
public class TestDataSourceConfig {
@Bean(name = "sqlSessionFactoryPrimary")
@Primary
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("testDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
//如果使用xml写SQL的话在这里配置
//bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/datasource/*.xml"));
return bean.getObject();
}
@Bean(name = "transactionManagerPrimary")
@Primary
public DataSourceTransactionManager masterDataSourceTransactionManager(@Qualifier("testDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "sqlSessionTemplatePrimary")
@Primary
public SqlSessionTemplate masterSqlSessionTemplate(@Qualifier("sqlSessionFactoryPrimary") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
druid的操作 http://localhost:8080/druid/index.html,很强大
4 操作cache
starter-cache默认的cache操作
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
@EnableCaching 开启注解
缓存相关的操作
@Cacheable(value = "user", key = "#id")
@CachePut(value = "user", key = "#id")
@CacheEvict(value = "user", key = "#id")
操作redis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
redis基本操作
RedisTemplate redisTemplate;
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer(Object.class));
ValueOperations<String, Object> vo = redisTemplate.opsForValue();
vo.set(key, value);
ValueOperations<String, Object> vo = redisTemplate.opsForValue();
操作memcached
<dependency>
<groupId>net.spy</groupId>
<artifactId>spymemcached</artifactId>
<version>2.12.2</version>
</dependency>
5 写日志
- 默认支持logback
- log4j
- log4j2
- elk日志收集:es,logstash,kibana
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>5.3</version>
</dependency>
1. 支持直接收集日志到es,给es压力较大
2. 使用kafka队列收集日志
6 安全之旅
安全框架shiro(身份验证,授权,会话管理,加密)
- 验证用户身份
- 为用户执行访问控制
- 使用session api
- 身份验证,回话事件做出控制
- 聚合数据源
- 单点登录
提供的功能
- web支持,缓存,并发,测试,运行方式,记住用户状态
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
# 配置shiro
* SecurityManager 实现安全管理
* ShiroFilterFactoryBean 实现过滤
* 设置安全管理
* 设置拦截器:filterChainDefinitionMap
* shiro 注解 AuthorizationAttributeSourceAdvisor
* 异常处理 SimpleMappingExceptionResolver
# 实现AuthorizingRealm,进行角色控制
* doGetAuthenticationInfo验证登录
* doGetAuthorizationInfo获取角色的授权列表
spring-security
实现UserDetailsService接口
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUserName(username);
if (user == null){
throw new UsernameNotFoundException("用户不存在!");
}
List<SimpleGrantedAuthority> simpleGrantedAuthorities = new ArrayList<>();
for (Role role : user.getRoleList()) {
simpleGrantedAuthorities.add(new SimpleGrantedAuthority(role.getRoleName()));
}
return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getPassWord(), simpleGrantedAuthorities);
}
在WebSecurityConfigurerAdapter上配置
* 支持数据库和密码认证
* configureGlobal
* configure
httpSecurity
.authorizeRequests()
.antMatchers("/css/**", "/index").permitAll()
.antMatchers("/select").hasRole("USER")
.antMatchers("/delete").hasRole("ADMIN");
7 监控
actuator监控
端点 /actuator/ /actuator/health
management.endpoint.shutdown.enabled= true
#开启全部
management.endpoints.web.exposure.include= *
#开启个别端点
#management.endpoints.web.exposure.include= heapdump,env
#鉴权使用
spring.security.user.name=admin
spring.security.user.password=123456
spring.security.user.roles=ENDPOINT_ADMIN
#显示详细信息
management.endpoint.health.show-details=always
加密
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
重新显示health: public class MyHealthIndicator implements HealthIndicator
可以重写路径的方法比如http://127.0.0.1:8080/actuator/health
image.png
admin监控
1. 通过http注册信息
2. admin-server通过服务发现的client收集客户端的信息
注册server
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
注册client
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.0.3</version>
</dependency>
admin-server:http://127.0.0.1:8080/#/applications
eureka-server:http://127.0.0.1:8761/
image.png
prometheus+grafana监控
普罗米修斯注册
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
使用
@Bean
MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
return registry -> registry.config().commonTags("application", applicationName);
}
访问
http://127.0.0.1:8080/actuator/prometheus
image.png












网友评论