Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。
一、 Spring Boot环境搭建
- JDK 和 Maven 下载
JDK:http://www.oracle.com // 访问 oracle 官网
Maven: http://maven.apache.org/download.cgi // 访问 apache 官网
- 配置 JDK 和 Maven 的环境变量
- 更换 IDEA Maven 设置
二、依赖注入
在 Spring Boot 中,依赖注入是一种核心的概念,它使您能够将一个对象的依赖关系(或依赖项)注入到另一个对象中,而不必明确创建这些依赖项。这有助于实现松散耦合,使代码更加模块化、可维护和可测试。
- 注入方式
Spring Boot 支持多种依赖注入方式,包括构造函数注入、Setter 方法注入和字段注入。构造函数注入是推荐的方式,因为它使得对象的依赖关系在创建时就能够得到满足。
@Service
public class MyService {
private final MyRepository repository;
@Autowired
public MyService(MyRepository repository) {
this.repository = repository;
}
// ...
}
- @Autowired 注解
在 Spring Boot 中,@Autowired
注解是最常用的方式来实现依赖注入。您可以将它应用在构造函数、Setter 方法或字段上,以注入其他 Spring Bean。
@Service
public class MyService {
@Autowired
private MyRepository repository;
// ...
}
- 依赖的管理
Spring Boot 应用程序的依赖项通常在应用程序的上下文(ApplicationContext)中管理。Spring Boot会自动扫描和创建这些 Bean,以供其他 Bean 使用。
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfiguration {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated();
http.formLogin().permitAll();
return http.build();
}
}
- 自定义配置
可以自定义配置文件,如 application.properties
或 application.yml
,来定义 Bean 的属性。这些属性可以在应用程序启动时加载并自动注入到 Bean 中。
- Qualifier 注解
当有多个具有相同类型的 Bean 时,可以使用 @Qualifier
注解指定要注入的 Bean 的名称。
@Service
public class MyService {
@Autowired
@Qualifier("myRepository1")
private MyRepository repository;
// ...
}
- Profile 注解
Spring Boot 提供了@Profile
注解,它可以用来指定哪个 Bean 应该在不同的应用程序配置环境中进行注入。这对于分别为开发、测试和生产环境提供不同的配置非常有用。
三、Spring Boot 三层架构
我们在进行前后端交互的时候,会分为数据访问,业务逻辑,接受请求并响应数据三个操作,这三个部分其实是可以拆分的,让他们解耦,否则代码复用性差并且不易维护,所以诞生了三层架构——1.Dao(数据访问层/持久层)、2.Service(业务逻辑层)、3.Controller(控制层)
- Dao(数据访问层/持久层)
负责数据访问操作,包括增删改查
- Service(业务逻辑层)
处理具体的业务逻辑,同样也采用接口的形式,Service层可以通过获取Dao层的数据,对数据内部进行处理,然后再返回,接下来给Controller调用
- Controller(控制层)
接收前端发送的请求,对请求进行处理并响应数据
我们在Controller中接受请求 ,调用Service进行逻辑处理,而Service中要调用Dao中的方法获取解析得到的数据,一层一层递进,分工明确,程序复用性大大提高。
四、Spring Boot 和数据库操作
Spring Boot 是一个开源的 Java 开发框架,它可以帮助开发者更快速地创建基于 Java 的应用程序。Spring Boot 提供了众多功能和库,用于简化应用程序的开发,其中包括数据库操作。
-
添加 pom 依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
- 添加数据源
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/javaweb
username: root
password: 123456
mybatis-plus:
type-aliases-package: com.example.demo.domain
- 生成相关文件
- 设置 Mapper 包扫描
@MapperScan("com.example.security.mapper")
@SpringBootApplication
public class SecurityApplication {
public static void main(String[] args) {
SpringApplication.run(SecurityApplication.class, args);
}
}
- 测试
@SpringBootTest
class SecurityApplicationTests {
@Autowired
private UsersMapper usersMapper;
@Test
void contextLoads() {
List<Users> users = usersMapper.selectList(null);
System.out.println("users = " + users);
}
}
五、Spring Boot 和 Redis
在Spring Boot中,与Redis集成进行数据缓存管理非常常见。Redis是一个高性能的内存键值存储数据库,适用于缓存数据和会话管理。
- 添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 配置Redis连接
spring:
data:
redis:
host: 127.0.0.1
port: 6379
lettuce:
pool:
max-active: 10
max-idle: 10
min-idle: 1
time-between-eviction-runs: 10s
- 写入 server 中
@Resource
private StringRedisTemplate stringRedisTemplate;
@Override
public Result queryById(Long id) {
String key = CACHE_SHOP_KEY + id;
String shopjson = stringRedisTemplate.opsForValue().get(key);
if (StrUtil.isNotBlank(shopjson)) {
Shop shop = JSONUtil.toBean(shopjson, Shop.class);
return Result.ok(shop);
}
Shop shop = getById(id);
if (shop == null) {
stringRedisTemplate.opsForValue().set(key,"",CACHE_NULL_TTL,TimeUnit.MINUTES);
return Result.fail("店铺不存在");
}
stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shop),CACHE_SHOP_TTL, TimeUnit.MINUTES);
return Result.ok(shop);
}
- redis更新策略
缓存-数据库双写一致性策略”,有时也称为“缓存-数据库双写同步策略”。它的基本思想是在更新数据库后,同步删除或更新相关的缓存,以确保缓存数据与数据库数据保持一致。
@Resource
private StringRedisTemplate stringRedisTemplate;
@Override
public Result shopUpdate(Shop shop) {
Long id = shop.getId();
if (id == null) {
return Result.fail("店铺id不能为空!!!");
}
// 1. 更新数据库
updateById(shop);
// 2. 删除缓存
stringRedisTemplate.delete(CACHE_SHOP_KEY + id);
return Result.ok();
}
- redis缓存穿透
合使用布隆过滤器、缓存空对象和定时刷新缓存的方法
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private RedisTemplate<String, User> redisTemplate;
@Value("${cache.expire-time}") // 从配置文件获取缓存超时时间
private long cacheExpireTime;
// 使用布隆过滤器
@Autowired
private BloomFilter<String> bloomFilter;
public User getUserById(String userId) {
// 先从布隆过滤器检查
if (!bloomFilter.mightContain(userId)) {
return null; // 用户ID肯定不存在
}
// 尝试从缓存中获取用户
String cacheKey = "user_" + userId;
ValueOperations<String, User> ops = redisTemplate.opsForValue();
boolean hasKey = redisTemplate.hasKey(cacheKey);
if (hasKey) {
return ops.get(cacheKey);
} else {
// 从数据库中获取用户信息
User user = userRepository.findById(userId).orElse(null);
// 用户存在,放入缓存
if (user != null) {
ops.set(cacheKey, user, cacheExpireTime, TimeUnit.MINUTES);
} else {
// 用户不存在,设置一个空对象到缓存
ops.set(cacheKey, new User(), cacheExpireTime, TimeUnit.MINUTES);
}
return user;
}
}
}
配置布隆过滤器
@Configuration
public class BloomFilterConfig {
@Value("${bloom-filter.expected-elements}")
private long expectedElements;
@Value("${bloom-filter.false-positive-probability}")
private double falsePositiveProbability;
@Bean
public BloomFilter<String> bloomFilter() {
return BloomFilter.create(
Funnels.stringFunnel(Charset.defaultCharset()),
expectedElements,
falsePositiveProbability);
}
}
- 缓存雪崩
缓存雪崩是指在某个时间点,缓存中的大量数据同时失效,导致大量请求直接打到数据库上,使数据库负载急剧上升。这通常发生在缓存中的数据具有相同的过期时间,或者因某种原因在同一时间内大量数据失效并被同时重新加载。
创建缓存管理器
在你的Spring Boot应用中创建一个缓存管理器类,它将处理缓存操作。这里我们使用Guava Cache。
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
public class CacheManager {
private Cache<String, String> cache;
public CacheManager() {
// 创建一个Guava缓存,设置合理的过期时间
cache = CacheBuilder.newBuilder()
.maximumSize(1000) // 设置最大缓存大小
.expireAfterWrite(5, TimeUnit.MINUTES) // 设置数据在写入后5分钟过期
.build();
}
public String getFromCache(String key) {
return cache.getIfPresent(key);
}
public void addToCache(String key, String value) {
cache.put(key, value);
}
}
创建业务逻辑
创建一个Service,模拟从数据库中获取数据并使用缓存。在这个示例中,我们将使用一个简单的字符串作为模拟数据
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DataService {
@Autowired
private CacheManager cacheManager;
public String getData(String key) {
String cachedData = cacheManager.getFromCache(key);
if (cachedData != null) {
return cachedData;
}
// 模拟从数据库或其他数据源中获取数据
String newData = "Data for key: " + key;
// 将数据放入缓存
cacheManager.addToCache(key, newData);
return newData;
}
}
学习回顾总结
在我进行Spring Boot学习的过程中,我积累了许多宝贵的经验和知识。以下是我学到的一些关键点:
-
Spring Boot简化了开发:Spring Boot的自动配置和自动化依赖管理使得创建Java应用程序变得轻松。不再需要花费大量时间配置项目。
-
Spring Boot Starter的强大:Spring Boot Starter依赖是一种快速启动不同类型应用程序的有效方式。我学会了如何根据需要选择适当的Starter。
-
数据库集成变得容易:Spring Boot对数据库集成提供了很好的支持。我了解了如何配置数据源、使用JPA和Spring Data简化数据访问。
-
Web开发的快速启动:Spring Boot使得Web应用程序的创建变得轻松。我学习了如何构建RESTful API、处理表单提交、和管理异常。
-
安全性和身份验证:学习如何使用Spring Security增强应用程序的安全性对我来说非常重要。我了解了如何配置身份验证和授权。
-
部署和监控:我也了解了应用程序的部署选项,包括如何将应用程序部署为独立应用、使用Docker容器化以及在云平台上进行部署。监控和日志记录对于应用程序的健康非常重要。
总的来说,Spring Boot是一个强大的工具,可以极大地提高Java应用程序的开发效率。通过学习,我感到更加自信,能够构建出高效、可维护的应用程序。在未来,我计划继续深入研究Spring Boot并将其应用于实际项目中,以不断提升我的开发技能。
这是一个简单的学习回顾总结,你可以根据你的实际经验和收获来定制总结。希望这对你的学习回顾有所帮助!