学生程序设计能力提升平台源码分析(三)Controller层源码分析之工具类及注解的内部实现原理

前言

2021SC@SDUSC

概述

本篇博客延续上次的话题,对项目Controller层源码进行进一步分析

源码

源码如下:

​


@RestController
@RequestMapping("/problemset")
public class ProblemsetController {

    @Autowired
    private ProblemsetService problemsetService;

    @Autowired
    private ProblemService problemService;

    private final Logger log = LoggerFactory.getLogger(ProblemController.class);


    @PostMapping("/getProblemset")
    @PreAuthorize("hasRole('ROLE_COMMON')")
    public ResultEntity getProblemset(@RequestParam("id") int id) {
        try {
            Problemset problemset = problemsetService.getProblemset(id);
            List<Problem> problemList = problemsetService.getProblemList(id);
            problemset.setProblems(problemList);
            return ResultEntity.success("题目集", problemset);
        } catch (Exception e) {
            log.error("查看题目集错误", e);
            return ResultEntity.error("查看题目集错误,请重试");
        }
    }

}

​

在上一篇博客中已经分析了两个注解的实现原理:@RestController 和 @RequestMapping

下面我们将对其余关键点进行分析

@Autowired实现原理

使用方法

目前@Autowired最常用的使用方法有两种:

1.属性注入:

public Class Outer {
    @Autowired
    private Inner inner;
}

2.方法注入:

public Class Outer {
    private Inner inner;
    public Inner getInner() {
        return inner;
    }
    @Autowired
    public void setInner(Inner inner) {
        this.inner = inner;
    }
}

这两种使用方法的内部实现原理其实是一样的

源代码

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
    boolean required() default true;
}

分析原理

其实基本原理比较简单,主要也是利用了Java的反射机制。在容器启动,为对象赋值的时候,遇到@Autowired注解,会用后置处理器机制,来创建属性的实例,然后再利用反射机制,将实例化好的属性,赋值给对象上,这就是Autowired的原理。

具体代码流程可以参考:

@Autowired注解注入实现原理_小燃儿的博客-CSDN博客_autowired实现原理

slf4j日志

对应代码:

private final Logger log = LoggerFactory.getLogger(ProblemController.class);

和catch Exception后:

log.error("查看题目集错误", e);

是关于slf4j日志插件的使用,网上也有很多教程和解释,这里不是我们的关键代码,因此不再赘述,有兴趣的可以自行了解

@PostMapping实现原理

使用

@PostMapping(value = "/user/login")

等价于

@RequestMapping(value = "/user/login",method = RequestMethod.POST)

其实@PostMapping是一个复合注解,相当于@RequestMapping对于POST模式的简化版本

源代码

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(
    method = {RequestMethod.POST}
)
public @interface PostMapping {
    @AliasFor(
        annotation = RequestMapping.class
    )
    String name() default "";

    @AliasFor(
        annotation = RequestMapping.class
    )
    String[] value() default {};

    @AliasFor(
        annotation = RequestMapping.class
    )
    String[] path() default {};

    @AliasFor(
        annotation = RequestMapping.class
    )
    String[] params() default {};

    @AliasFor(
        annotation = RequestMapping.class
    )
    String[] headers() default {};

    @AliasFor(
        annotation = RequestMapping.class
    )
    String[] consumes() default {};

    @AliasFor(
        annotation = RequestMapping.class
    )
    String[] produces() default {};
}

分析原理

我们可以很清楚的看到,其内部就是对于@RequestMapping的一层封装,内部默认RequestMapping的method为POST,其实是对于Restful风格的一种支持

以下同类型注解:
@GetMapping、@PutMapping、@PatchMapping和@DeleteMapping,与@PostMapping实现类似

总结

至此,Controller层源码已经快要分析完成了,预计下一篇博客会完成收尾并开启下一个专题分析,希望大家能在会使用的同时,对代码的内部实现有更深入的理解。

参考资料

spring源码16: @Autowired实现原理_bugpool的博客-CSDN博客_@autowired实现原理

https://segmentfault.com/a/1190000018077152

Spring MVC的@PostMapping注解 - 程序员大本营


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值