在 Spring 框架中,`@Component` 和 `@Configuration` 注解用于不同的目的,尽管它们都可以将类注册为 Spring 容器中的 Bean。下面详细解释这两个注解的区别以及为什么在你的示例中一个使用 `@Component`,另一个使用 `@Configuration`。
@Component 注解
用途:
`@Component` 是一个通用的注解,用于标记任何 Spring 管理的组件。它可以用于服务层(Service)、数据访问层(Repository)、控制器(Controller)等任何组件。
自动扫描:
当 Spring 启动时,它会自动扫描带有 `@Component` 注解的类,并将其注册为 Bean。通常与 `@ComponentScan` 注解一起使用,指定扫描的包路径。
- **示例**:
```java
import org.springframework.stereotype.Component;
@Component
public class JwtTokenAdminInterceptor implements HandlerInterceptor {
// 实现拦截器逻辑
}
```
@Configuration 注解
用途:
`@Configuration` 注解用于标记一个类,表明该类包含一个或多个 `@Bean` 方法,这些方法返回的对象会被 Spring 容器管理。它通常用于配置类,定义应用程序的配置细节。
Bean 定义:
在 `@Configuration` 类中,你可以使用 `@Bean` 注解的方法来定义和配置 Bean。
这些 Bean 可以被其他组件注入和使用。
- **示例**:
```java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private JwtTokenAdminInterceptor jwtTokenAdminInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtTokenAdminInterceptor)
.addPathPatterns("/**");
}
}
```
为什么一个使用 @Component,另一个使用 @Configuration
1. JwtTokenAdminInterceptor 类:
- **用途**:这是一个拦截器,用于处理 HTTP 请求的拦截和 JWT 验证。
- **注册方式**:使用 `@Component` 注解,让 Spring 自动扫描并将其注册为 Bean。
- **优点**:简单直接,适用于普通的组件类。
2. WebConfig 类:
- **用途**:这是一个配置类,用于配置 Spring MVC 的拦截器和其他相关设置。
- **注册方式**:使用 `@Configuration` 注解,表明这是一个配置类,并且可以包含 `@Bean` 方法。
- **优点**:明确表示这是一个配置类,便于管理和维护。
### 示例代码解释
#### JwtTokenAdminInterceptor 类
```java
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
@Component
public class JwtTokenAdminInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 获取请求路径
String requestURI = request.getRequestURI();
// 排除不需要验证的路径
if (requestURI.equals("/admin/employee/login")) {
return true; // 直接放行
}
// 获取 Authorization 头
String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("Missing or invalid Authorization header");
return false; // 验证失败
}
// 提取 JWT
String token = authHeader.substring(7);
// 验证 JWT
if (isValidToken(token)) {
return true; // 验证通过,继续处理请求
} else {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("Invalid JWT token");
return false; // 验证失败
}
}
private boolean isValidToken(String token) {
// 实现 JWT 验证逻辑
try {
Jwts.parser()
.setSigningKey("your_secret_key")
.parseClaimsJws(token);
return true; // 验证通过
} catch (Exception e) {
return false; // 验证失败
}
}
}
```
@Component:标记为 Spring 管理的组件,自动扫描并注册为 Bean。
#### WebConfig 类
```java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private JwtTokenAdminInterceptor jwtTokenAdminInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtTokenAdminInterceptor)
.addPathPatterns("/**"); // 拦截所有路径
}
}
```
@Configuration:标记为配置类,包含 Spring MVC 的配置。
WebMvcConfigurer:实现该接口以配置拦截器和其他 MVC 设置。
总结
@Component 用于标记普通的 Spring 组件,如拦截器、服务、控制器等。
@Configuration用于标记配置类,包含 Bean 定义和配置设置。
通过这种方式,你可以清晰地区分组件和服务配置,使代码更加模块化和易于维护。