前言
在使用Spring Boot
框架的开发时,"上下文" 是一个非常重要的概念。上下文(Context)不仅帮助我们在应用程序的不同部分传递信息,还能用于管理应用的配置和状态。之前不太理解上下文,其实我门早就是使用到了上下文的概念了,继续往下看,你肯定用到过下面功能。
什么是上下文?
上下文,顾名思义是指程序执行时的一种环境信息或状态,通常包含了当前请求、配置、资源等一系列信息。在Spring Boot中,上下文可以被视为一个容器,用于存储和管理应用程序的配置信息、对象实例(Bean)以及它们之间的依赖关系。这个容器是整个应用程序运行的基础,负责组织和管理不同模块的交互。
上下文作用
存储配置信息:上下文通常包含应用程序的全局配置信息,比如数据库配置、缓存配置等。这些信息在整个应用程序中共享。
管理 Bean
生命周期:Spring
的上下文可以创建、管理、销毁 Bean
,并负责 Bean
之间的依赖注入,简化了开发过程。
资源共享:上下文允许不同模块或组件之间共享数据或资源,避免重复配置和数据传递。
应用事件管理:上下文还可以用来监听和处理应用程序中的事件,如应用启动、关闭、异常等。
为什么要有上下文?
依赖注入的基础
在传统的面向对象编程中,类与类之间的依赖关系通常通过构造函数、工厂方法等方式进行显式地管理。这种方式往往会导致代码的耦合度较高,并且增加了维护难度。而上下文为开发者提供了一种简洁的依赖注入机制。Spring Boot
使用上下文来管理应用程序中的 Bean
。通过上下文,开发者可以轻松地将类的依赖注入到其他类中,而不需要手动实例化这些类。Spring
上下文自动负责这些 Bean
的创建、初始化、销毁等生命周期管理。
例如,在一个 Spring Boot
项目中,假设我们有一个 UserServiceImpl
依赖于 UserRepository
:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
public User getUserById(Long id) {
return userRepository.findById(id).orElseThrow(EntityNotFoundException::new);
}
}
在这个例子中,UserServiceImpl
并不需要显式地创建 UserRepository
实例。Spring Boot
的上下文会根据注解(如 @Autowired
)自动将 UserRepository
注入到 UserServiceImpl
中,从而极大地简化了对象的依赖管理。
配置的集中管理
当我门在团队开发的时候,每个人的电脑环境不一样,这个时候我们可以将这些配置信息集中管理,避免在代码中硬编码配置,并且能够根据不同环境灵活切换配置。
在application.yml
文件定义配置时,这些配置会被自动加载到上下文中,供应用的各个部分使用。例如:
spring:
config:
activate:
on-profile: ZJ-TUTE
datasource:
url: "jdbc:mysql://localhost:3307/minio-brower?characterEncoding=utf-8"
username: "root"
password: "123456"
事件驱动机制
即当应用程序中的某些操作或状态变化时,可以发布事件,相关的组件可以监听并响应这些事件。
例如,我们可以监听应用程序启动事件,执行一些初始化操作,例如:
@Component
public class InitUser implements ApplicationListener<ContextRefreshedEvent>, Ordered {
public static int order = Integer.MIN_VALUE;
private static final Logger logger = LoggerFactory.getLogger(InitUser.class);
private final UserRepository userRepository;
public InitUser(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
logger.info("初始化用户");
if (userRepository.count() == 0) {
User user = new User();
user.setName("admin");
user.setUsername("admin");
user.setPassword("admin");
userRepository.save(user);
}
}
当项目启动的时候,就会先初始化一个用户。
上下文的实际应用场景
Web 应用中的上下文
在 Web 应用中,我们可以通过上下文获取与请求、会话相关的信息。例如:
@PostMapping(produces = "text/xml; charset=UTF-8")
public void api(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
@RequestParam("signature") String signature,
@RequestParam(name = "encrypt_type", required = false) String encType,
@RequestParam(name = "msg_signature", required = false) String msgSignature,
@RequestParam("timestamp") String timestamp,
@RequestParam("nonce") String nonce) throws IOException {
}
通过 HttpServletRequest
获取当前请求信息,HttpServletResponse
代表响应的上下文,用于构建返回给客户端的响应。
配置文件的注入与使用
在上下文中将外部配置文件中的参数直接注入到某个类中。例如,假设我们在 application.yml
文件中定义了一些应用配置:
我们可以通过 @Value
注解将这些配置注入到类中:
@Value("${wx.mp.token}")
private String token;
@Value("${wx.mp.appid}")
private String appid;
@Value("${wx.mp.secret}")
private String appSecret;
@Value("${wx.mp.aesKey}")
private String aesKey;
通过上下文,Spring Boot
自动加载配置文件并解析其中的配置参数。
安全上下文的使用
在安全框架中,安全上下文用于存储当前用户的身份信息和权限信息。Spring Security
提供了 SecurityContextHolder
类,它封装了用户认证和授权的上下文信息。
例如,我们可以通过安全上下文获取当前用户的身份信息:
@GetMapping("/currentUser")
public String getCurrentUser() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
//当前用户
return authentication.getName();
}
SecurityContextHolder
是 Spring Security
的上下文管理器,它提供了关于当前用户的安全信息。
总结
当初始化一个Spring
项目时,实际上已经在使用Spring
的上下文。上下文在应用启动时被创建并充当应用的核心管理者,会扫描、注册、管理Bean,提供全局的配置、事件管理等一些 功能。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。