Spring常用注解

Spring常用注解

Web

@Controller

组合注解:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component

应用在 MVC 层(控制层),以前在编写Controller方法的时候,需要开发者自定义一个Controller类实现Controller接口,实现handleRequest方法返回ModelAndView。并且需要在Spring配置文件中配置Handle,将某个接口与自定义Controller类做映射。

在采用@Contoller注解的方式,可以使接口的定义更加简单,将@Controller标记在某个类上,配合@RequestMapping注解,可以在一个类中定义多个接口,这样使用起来更加灵活。

@RestController
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody

主要是@Controller和@ResponseBody组合注解

@ResponseBody
  • 数据序列化: 当一个控制器方法被标记为 @ResponseBody 时,Spring会使用一个合适的消息转换器(MessageConverter)将方法的返回值序列化为指定的格式(通常是JSON)。Spring框架内置了多个消息转换器,可以处理多种数据格式,包括JSON、XML等。
  • HTTP响应构建:将序列化后的数据作为HTTP响应的主体,同时设置正确的Content-Type头部,以指示响应的数据格式。例如,如果返回的是JSON数据,Content-Type会被设置为application/json。
  • 发送响应: 框架最终将包含序列化数据的HTTP响应发送到客户端。
@RequestMapping

是Spring框架中用于映射Web请求到特定处理方法的注解。它可以用于类级别(处理所有方法)或方法级别(只处理特定方法)。在Spring 4.3及之后的版本,@RequestMapping 被更具体的注解取代,比如 @GetMapping、@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping。

以下是 @RequestMapping 注解的主要原理:

路由映射: @RequestMapping 注解允许你将HTTP请求(GET、POST、PUT、DELETE等)映射到Java方法。当一个请求到达时,Spring的DispatcherServlet会根据URL路径以及请求的HTTP方法,找到匹配的 @RequestMapping 注解,然后调用相应的处理方法。

处理方法执行: 当 @RequestMapping 注解被匹配到时,关联的处理方法会被执行。这个方法通常包含了业务逻辑,它会处理请求,生成响应,并返回给客户端。

参数绑定: @RequestMapping 注解允许你使用方法的参数,这些参数会被自动从请求中提取,比如路径变量(@PathVariable)、请求参数(@RequestParam)、请求体(@RequestBody)等。这样,你可以方便地在处理方法中获取请求中的数据。

视图解析: 如果处理方法的返回类型是String,那么它通常被解释为视图的名称。Spring框架会使用视图解析器(ViewResolver)将这个逻辑视图名称解析为一个真正的视图,然后渲染它,将其作为HTTP响应的主体返回给客户端。在RESTful服务中,通常返回的是数据对象(比如JSON对象),而不是视图名称。

@RequestBody

@RequestBody 是 Spring MVC 框架中的注解,用于表示请求体的内容会被映射到方法参数上。它的原理涉及到 Spring MVC 的消息转换机制和处理请求的流程。

以下是 @RequestBody 的工作原理:

消息转换器: 当请求进入 Spring MVC 控制器时,Spring MVC 会使用消息转换器(MessageConverter)来处理请求的消息体。消息转换器负责将请求的内容转换为方法参数所需的类型。对于 @RequestBody,它主要负责将请求体的内容转换为方法参数的类型。

Content-Type 头: Spring MVC 会检查请求的 Content-Type 头,以确定如何解析请求体。@RequestBody 通常用于处理 JSON 或 XML 格式的请求体。

HttpMessageConverter 接口: 消息转换器是通过实现 HttpMessageConverter 接口来实现的。HttpMessageConverter 提供了两个关键方法:canRead() 和 read()。canRead() 用于检查是否可以将请求体内容转换为指定的 Java 类型,而 read() 则用于执行实际的转换操作。

MappingJackson2HttpMessageConverter: 在处理 JSON 格式的请求体时,通常会使用 MappingJackson2HttpMessageConverter,它是 Spring 提供的将 JSON 转换为 Java 对象的消息转换器。

当控制器方法参数使用 @RequestBody 注解时,Spring MVC 将使用适当的消息转换器将请求体内容转换为方法参数的类型。

下面是一个简单的示例:

@RestController
public class MyController {

    @PostMapping("/example")
    public ResponseEntity<String> handleRequest(@RequestBody MyObject myObject) {
        // 处理 myObject 对象
        return ResponseEntity.ok("Request handled successfully");
    }
}

在这个例子中,@RequestBody 将请求体中的 JSON 数据转换为 MyObject 类型的对象。

需要注意的是,为了使用 @RequestBody,你需要确保在你的项目中包含了适当的消息转换器,例如 Jackson 库用于 JSON 转换。在大多数情况下,Spring Boot 会自动配置这些转换器,你只需要添加相关的依赖。

@PathVariable

@PathVariable 是 Spring MVC 框架中的注解,用于将 URI 模板变量映射到控制器方法的参数上。这个注解的工作原理涉及到 Spring MVC 的路径匹配和参数绑定机制。

以下是 @PathVariable 的工作原理:

URI 模板: 在 Spring MVC 中,你可以在请求的 URL 中定义变量,这些变量被包含在大括号 {} 中,例如 /users/{userId}。这些被大括号包围的部分就是 URI 模板变量。

@PathVariable 注解: 当控制器方法的参数使用 @PathVariable 注解标注时,Spring MVC 会将匹配的 URI 模板变量的值绑定到这个参数上。

匹配过程: Spring MVC 在接收到请求时,会根据请求的 URL 进行路径匹配。如果路径中包含 URI 模板变量,它会尝试将请求的实际值映射到控制器方法的参数。

示例: 以下是一个简单的示例,演示了 @PathVariable 的使用:

@RestController
public class MyController {

    @GetMapping("/users/{userId}")
    public ResponseEntity<String> getUserById(@PathVariable Long userId) {
        // 处理 userId
        return ResponseEntity.ok("User ID: " + userId);
    }
}

在这个例子中,@PathVariable 用于将 URI 模板变量 {userId} 的值绑定到 getUserById 方法的 userId 参数上。例如,对于 /users/123 的请求,userId 将被映射为 123。

需要注意的是,默认情况下,@PathVariable 的名称与 URI 模板变量的名称一致,但你也可以通过指定名称来明确映射。例如:

@GetMapping("/users/{userId}/orders/{orderId}")
public ResponseEntity<String> getOrderById(@PathVariable("userId") Long userId, @PathVariable("orderId") Long orderId) {
    // 处理 userId 和 orderId
    return ResponseEntity.ok("User ID: " + userId + ", Order ID: " + orderId);
}

在这个例子中,userId 和 orderId 参数分别映射到 URI 模板变量 {userId} 和 {orderId}。

容器

@component

@Component 注解是 Spring 框架中用于声明一个类为 Spring 组件的注解。被 @Component 标记的类会被 Spring 自动扫描,并注册为 Spring 容器中的一个 Bean。这个注解的原理主要涉及到 Spring 的组件扫描和Bean的注册。

以下是 @Component 注解的工作原理:

组件扫描: Spring 框架通过组件扫描机制来寻找带有 @Component 注解的类。组件扫描是 Spring 自动发现和注册 Bean 的一种机制。

配置扫描路径: 在 Spring 配置中,你需要配置组件扫描的路径。这可以通过在配置类上使用 @ComponentScan 注解来实现。例如:

@Configuration
@ComponentScan("com.example")
public class AppConfig {
    // 配置信息
}

这告诉 Spring 在 com.example 包及其子包中查找带有 @Component 注解的类。

Bean 的注册: 当 Spring 发现一个带有 @Component 注解的类时,它会将这个类实例化,并将其注册为一个 Bean。这样,这个 Bean 就能够被其他类依赖注入或者通过 ApplicationContext 获取。

其他派生注解: 除了 @Component,Spring 框架还提供了一系列派生注解,如 @Service、@Repository、@Controller 等。这些注解实际上都是 @Component 的特化,用于表示不同角色的组件。例如,@Service 用于标识服务层的组件,@Repository 用于标识数据访问层的组件。

@Service
public class MyService {
    // 服务层的逻辑
}

这样标注的类会被 Spring 框架特殊对待,但其实现原理与 @Component 是类似的。

总体来说,@Component 注解的原理是通过组件扫描机制,将标注为 @Component 的类实例化并注册为 Spring 容器中的 Bean。这使得 Spring 框架能够管理和维护这些组件,并提供依赖注入等特性。

@Autowired

@Autowired 注解是 Spring 框架中用于自动注入依赖的注解。它的原理主要涉及到 Spring IoC 容器和依赖注入的实现。

以下是 @Autowired 注解的工作原理:

  • 自动装配: @Autowired 注解是 Spring 的自动装配(autowiring)机制的一部分。它能够在 Spring IoC 容器中自动寻找匹配某个类型的 Bean,并将其注入到标注了 @Autowired 的字段、方法或构造函数中。
  • 类型匹配: 当 Spring 遇到一个被 @Autowired 标注的元素时,它会尝试找到与该元素类型匹配的
    Bean。如果找到多个匹配项,Spring 将根据不同的条件(例如按照 Bean 名称或使用 @Qualifier 注解)进行解决。
  • 字段注入: 在字段上使用 @Autowired 注解时,Spring 将尝试将匹配的 Bean 注入到该字段。
@Component
public class MyService {
    // ...
}

@Component
public class MyComponent {
    @Autowired
    private MyService myService;
}
  • 方法注入: 在方法上使用 @Autowired 注解时,Spring 将尝试调用匹配的 Bean 并将其作为方法参数传递进来。
@Component
public class MyComponent {
    private MyService myService;

    @Autowired
    public void setMyService(MyService myService) {
        this.myService = myService;
    }
}
  • 构造函数注入: 在构造函数上使用 @Autowired 注解时,Spring 将尝试调用匹配的 Bean 并将其作为构造函数参数传递进来。
@Component
public class MyComponent {
    private MyService myService;

    @Autowired
    public MyComponent(MyService myService) {
        this.myService = myService;
    }
}

总体来说,@Autowired 注解的原理是通过 Spring IoC 容器实现的,Spring 会在容器中查找匹配的 Bean,并将其自动注入到标注了 @Autowired 的元素中。这样就实现了方便的依赖注入,提高了代码的灵活性和可维护性。

@Qualifier

限定符(Qualifier): 如果存在多个符合条件的 Bean,可以使用 @Qualifier 注解指定具体要注入的 Bean 名称。

@Component
@Qualifier("specificService")
public class SpecificService implements MyService {
    // ...
}

@Component
public class MyComponent {
    @Autowired
    @Qualifier("specificService")
    private MyService myService;
}
@Configuration

@Configuration 注解是 Spring 框架中用于声明配置类的注解。配置类通常包含用 @Bean 注解标记的方法,这些方法返回的对象会被注册到 Spring IoC 容器中。下面是 @Configuration 注解的一些原理和工作方式:

标记配置类: 使用 @Configuration 注解来标记一个类为配置类。

@Configuration
public class AppConfig {
    // Bean definitions using @Bean
}

配置类特殊处理: Spring 在扫描组件时特殊处理带有 @Configuration 注解的类,以识别其中定义的 Bean。

Bean 方法: 在配置类中,通过 @Bean 注解标记的方法用于声明 Bean 的定义。这些方法将被 Spring IoC 容器调用,其返回值将被注册为一个 Bean。

@Configuration
public class AppConfig {

    @Bean
    public MyBean myBean() {
        return new MyBean();
    }
}

Bean 的注册: 在运行时,当 Spring IoC 容器初始化时,它会扫描配置类,解析 @Bean 注解,调用相应的方法,将方法返回的对象注册到容器中。

依赖注入: @Configuration 类中的 @Bean 方法可以使用其他 Bean 作为参数,实现依赖注入。

@Configuration
public class AppConfig {

    @Bean
    public MyBean myBean() {
        return new MyBean();
    }

    @Bean
    public AnotherBean anotherBean(MyBean myBean) {
        return new AnotherBean(myBean);
    }
}

条件化配置: 可以使用条件化注解(如 @Conditional)在 @Bean 方法上,根据条件决定是否创建该 Bean。

@Configuration
public class AppConfig {

    @Bean
    @Conditional(DatabaseTypeCondition.class)
    public DataSource dataSource() {
        // 根据条件创建 DataSource
    }
}

总体而言,@Configuration 注解是 Spring 配置的基础。它告诉 Spring 这个类包含 Bean 的定义,Spring 在运行时会使用这些定义来创建 Bean,并将它们纳入 IoC 容器的管理。@Configuration 注解在 Java 配置中提供了一种强大的方式来配置 Spring 应用程序。

@Bean

@Bean 注解是 Spring Framework 中用于标记方法的注解,通常用于配置类中的方法。这个注解告诉 Spring IoC 容器,方法的返回值应该被注册为一个 Bean,并被容器管理。以下是一些关键点和示例:

在配置类中使用 @Bean:

@Configuration
public class AppConfig {

    @Bean
    public MyBean myBean() {
        return new MyBean();
    }
}

返回的对象作为 Bean 注册:

myBean() 方法返回的对象(new MyBean())会被 Spring IoC 容器注册为一个 Bean。

这样,你可以在应用程序中通过注入方式使用 MyBean。

Bean 的名称: 默认情况下,@Bean 方法的名称与方法名相同。你可以通过 name 属性指定 Bean 的名称。

@Bean(name = "customName")
public MyBean myBean() {
    return new MyBean();
}

通过方法参数注入其他 Bean: @Bean 方法可以接受其他 Bean 作为参数,实现依赖注入。

@Bean
public AnotherBean anotherBean(MyBean myBean) {
    return new AnotherBean(myBean);
}

条件化 Bean 的创建: 可以使用条件化注解(如 @Conditional)来决定是否创建某个 Bean。

@Bean
@Conditional(DatabaseTypeCondition.class)
public DataSource dataSource() {
    // 根据条件创建 DataSource
}

生命周期管理: 你可以在 @Bean 方法上添加 @Scope 注解来定义 Bean 的作用域。

@Bean
@Scope("prototype")
public MyBean myBean() {
    return new MyBean();
}

初始化和销毁方法: 你可以在 @Bean 方法上使用 @PostConstruct 和 @PreDestroy 注解来指定初始化和销毁方法。

@Bean
@PostConstruct
public void init() {
    // 初始化逻辑
}

@Bean
@PreDestroy
public void destroy() {
    // 销毁逻辑
}

总之,@Bean 注解是定义 Spring Bean 的一种强大而灵活的方式。通过这个注解,你可以在配置类中声明 Bean,而这些 Bean 将被 Spring IoC 容器管理。

@Scope

@Scope 注解是 Spring Framework 提供的用于定义 Bean 作用域(Scope)的注解。通过 @Scope 注解,可以指定一个 Bean 的创建和销毁时机,以及它的作用域类型。

以下是 @Scope 注解的基本原理:

作用域类型: @Scope 注解的 value 属性用于指定 Bean 的作用域类型。常见的作用域类型包括:

  • singleton: 默认值,表示一个 Spring 容器中只有一个实例。
  • prototype: 每次注入或者通过 Spring 容器获取 Bean 时都会创建一个新的实例。
  • request: 每个 HTTP 请求都会创建一个新的 Bean 实例,仅在 Web-aware Spring
    ApplicationContext 中有效。
  • session: 每个 HTTP Session 都会创建一个新的 Bean 实例,仅在 Web-aware Spring
    ApplicationContext 中有效。
  • globalSession: 全局 HTTP Session,仅在 Web-aware Spring ApplicationContext
    中有效。
@Bean
@Scope("prototype")
public MyPrototypeBean myPrototypeBean() {
    return new MyPrototypeBean();
}

与作用域关联的是 Bean 的生命周期。对于 Singleton 作用域,Bean 的初始化和销毁是由 Spring 管理的;而对于 Prototype 作用域,Spring 不负责销毁 Bean,开发者需要手动管理。
Prototype Bean 并非必须手动销毁。它们的生命周期完全交给了应用程序代码。如果你的 Prototype Bean 不涉及到需要手动释放的资源,也没有必要执行特定的清理逻辑,那么你可以不必手动销毁它们。
在某些情况下,Prototype Bean 的无需手动销毁可能会更方便,因为它避免了在应用代码中添加繁琐的手动销毁逻辑。然而,如果 Prototype Bean 包含需要释放的资源或执行必要的清理工作,那么手动销毁是一个好的实践。

AOP

@Aspect 注解是 Spring AOP 中用于定义切面的注解。它告诉 Spring 这个类是一个切面,其中可能包含了切入点和通知。
假设你有一个服务类 MyService,包含一些方法,你想要创建一个切面,监控这些方法的执行。首先,你可以定义一个切入点表达式,然后在切面中引用这个切入点。

import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class MyAspect {

    // 定义切入点表达式
    @Pointcut("execution(* com.example.service.MyService.*(..))")
    private void myServiceMethods() {}

    // 在切入点之前执行的通知
    @Before("myServiceMethods()")
    public void beforeAdvice() {
        System.out.println("Before advice");
    }

    // 在切入点之后执行的通知
    @After("myServiceMethods()")
    public void afterAdvice() {
        System.out.println("After advice");
    }
}

在上面的例子中:

@Pointcut(“execution(* com.example.service.MyService.*(…))”) 定义了一个切入点表达式,表示匹配 MyService 类的所有方法。注解本身标记的方法不会执行,它只是用于定义切入点表达式,并允许在切面中引用这个切入点。切入点表达式定义了在何处、何时应用切面的通知。

@Before(“myServiceMethods()”) 和 @After(“myServiceMethods()”) 注解引用了上述切入点。这意味着 beforeAdvice 和 afterAdvice 方法将在匹配的方法执行之前和之后执行。

然后,你的 MyService 类可能如下所示:

import org.springframework.stereotype.Service;

@Service
public class MyService {

    public void doSomething() {
        System.out.println("Doing something");
    }

    public void doAnotherThing() {
        System.out.println("Doing another thing");
    }
}

当你调用 MyService 类的方法时,切面中的通知将会在方法执行前和执行后打印相应的信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值