常见的Annotation

JavaConfig的开始

Java 5 的推出,加上当年基于纯 Java Annotation 的依赖注入框架 Guice 的出现,使得 Spring 框架及其社区也“顺应民意”,推出并持续完善了基于 Java 代码和 Annotation 元信息的依赖关系绑定描述方式,即 JavaConfig 项目。

基于 JavaConfig 方式的依赖关系绑定描述基本上映射了最早的基于 XML 的配置方式,比如:

(1)表达形式层面

image

(2)注册 bean 定义层面

image

(3)表达依赖注入关系层面

image

在 JavaConfig 形式的依赖注入过程中,我们使用方法调用的形式注入依赖,如果这个方法返回的对象实例只被一个 bean 依赖注入,那也还好,如果多于一个 bean 需要依赖这个方法调用返回的对象实例,那是不是意味着我们就会创建多个同一类型的对象实例?

从代码表述的逻辑来看,直觉上应该是会创建多个同一类型的对象实例,但实际上最终结果却不是这样,依赖注入的都是同一个 Singleton 的对象实例,那这是如何做到的?

笔者一开始以为 Spring 框架会通过解析 JavaConfig 的代码结构,然后通过解析器转换加上反射等方式完成这一目的,但实际上 Spring 框架的设计和实现者采用了另一种更通用的方式,这在 Spring 的参考文档中有说明。即通过拦截配置类的方法调用来避免多次初始化同一类型对象的问题,一旦拥有拦截逻辑的子类发现当前方法没有对应的类型实例时才会去请求父类的同一方法来初始化对象实例,否则直接返回之前的对象实例。

所以,原来 Spring IoC 容器中有的特性(features)在 JavaConfig 中都可以表述,只是换了一种形式而已,而且,通过声明相应的 Java Annotation 反而“内聚”一处,变得更加简洁明了了。

补充:
@Scope

那些高曝光率的 Annotation(注解)

1、@Configuration

JavaConfig中的annotation,任何一个标注了 @Configuration 的 Java 类定义都是一个 JavaConfig 配置类。
https://www.cnblogs.com/duanxz/p/7493276.html

2、@ComponentScan

image

@Component: 标注Spring管理的Bean,使用@Component注解在一个类上,表示将此类标记为Spring容器中的一个Bean。

@Repository:@Repository本身是基于@Component注解的扩展,被@Repository注解的POJO类表示DAO层实现,从而见到该注解就想到DAO层实现,使用方式和@Component相同;

@Service:@Service本身是基于@Component注解的扩展,被@Service注解的POJO类表示Service层实现,从而见到该注解就想到Service层实现,使用方式和@Component相同;

@Controller:@Controller本身是基于@Component注解的扩展,被@Controller注解的类表示Web层实现,从而见到该注解就想到Web层实现,使用方式和@Component相同;

使用@Component,@Service,@Controller,@Repository注解的类,表示把这些类纳入到spring容器中进行管理,同时也是表明把该类标记为Spring容器中的一个Bean。

3、@PropertySource 与 @PropertySources

image

4、@Import 与 @ImportResource

image

5、@MapperScan(Mybatis自动生成文件用到)

@Mapper注解作用:
在接口类上添加了@Mapper,在运行时,通过动态代理生成的相应的接口实现类。
如果想要每个接口都要变成实现类,那么需要在每个接口类上加上@Mapper注解,比较麻烦,解决这个问题用@MapperScan。
添加位置:接口类上面:
image

@MapperScan注解作用:
作用:指定要变成实现类的接口所在的包,然后包下面的所有接口在编译之后都会生成相应的实现类
添加位置:是在Springboot启动类上面添加:
image

使用@MapperScan注解多个包示例:
image

6.@RestController

@RestController = @Controller + @ResponseBody

  • @Controller 将当前修饰的类注入SpringBoot IOC容器,使得从该类所在的项目跑起来的过程中,这个类就被实例化。当然也有语义化的作用,即代表该类是充当Controller的作用;
  • @ResponseBody 它的作用简单来说就是指该类中所有的API接口返回的数据,甭管你对应的方法返回Map或是其他Object,它会以Json字符串的形式返回给客户端,本人尝试了一下,如果返回的是String类型,则仍然是String。

示例代码:(这部分代码对于Map返回则是JSON String,对于String则仍然是String)

@RestController
@RequestMapping("test")
public class SampleController {

    @GetMapping
    public Map testGet() {
        return new HashMap<String, String>(){{
           put("name", "springboot");
        }};
    }

    @GetMapping(path = "str")
    public String testGetStr() {
        return "OK";
    }
}

效果:
image
image
当将@RestController换成@Controller之后,对于/test的返回值如下图:
image

从报错可以看见,当@Controller修饰的时候,Spring以为会返回一个View(也就是MVC中的那C)但是返回的东西却是一个Map。

7.@PathVariable

@PathVariable("xxx")

通过 @PathVariable 可以将URL中占位符参数{xxx}绑定到处理器类的方法形参中@PathVariable(“xxx“)

@RequestMapping(value=”user/{id}/{name}”)
请求路径:http://localhost:8080/hello/show5/1/james

实例:

    @RequestMapping("show5/{id}/{name}")
    public ModelAndView test5(@PathVariable("id") Long ids , @PathVariable("name") String names){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","占位符映射:id:"+ids+";name:"+names);
        mv.setViewName("hello2");
        return mv;
    }
}

8.@Param

@Param是MyBatis所提供的(org.apache.ibatis.annotations.Param),作为Dao层的注解,作用是用于传递参数,从而可以与SQL中的的字段名相对应,一般在2=<参数数<=5时使用最佳

实例:
1、
接口:

public List<Role> findRoleByAnnotation(@Param("roleName") String roleName, @Param("note") String note);

2、
也可以使用Java Bean来传递多个参数,定义一个POJO

public class RoleParam {
    private String roleName;
    private String note;
    /*getter和setter*/
}

此时接口就变为:

public List<Role> findRoleByMix(@Param("roleP") RoleParam role);

这样就可以进行如下映射:(就是当时项目中mybatis-generator生成的mapping文件夹下的映射文件中生成的**.xml对应内容)

<select id="findRoleByMix" resultType="role">
    SELECT id,name FROM t_role
    WHERE roleName=#{roleP.roleName}
    AND note=#{rolep.note}
    AND level=#{permissionP.level}
<select>
9.@RequestParam注解使用

@RequestParam:将请求参数绑定到你控制器的方法参数上(是springmvc中接收普通参数的注解)

语法:@RequestParam(value=”参数名”,required=”true/false”,defaultValue=””)

value:参数名

required:是否包含该参数,默认为true,表示该请求路径中必须包含该参数,如果不包含就报错。

defaultValue:默认参数值,如果设置了该值,required=true将失效,自动为false,如果没有传该参数,就使用默认值

@Controller
@RequestMapping("hello")
public class HelloController2 {

    /**
     * 接收普通请求参数
     * http://localhost:8080/hello/show16?name=linuxsir
     * url参数中的name必须要和@RequestParam("name")一致
     * @return
     */
    @RequestMapping("show16")
    public ModelAndView test16(@RequestParam("name")String name){
        ModelAndView mv = new ModelAndView();
        mv.setViewName("hello2");
        mv.addObject("msg", "接收普通的请求参数:" + name);
        return mv;
    }

 
    /**
     * 接收普通请求参数
     * http://localhost:8080/hello/show17
     * url中没有name参数不会报错、有就显示出来
     * @return
     */
    @RequestMapping("show17")
    public ModelAndView test17(@RequestParam(value="name",required=false)String name){
        ModelAndView mv = new ModelAndView();
        mv.setViewName("hello2");
        mv.addObject("msg", "接收普通请求参数:" + name);
        return mv;
    }

 

    /**
     * 接收普通请求参数
     * http://localhost:8080/hello/show18?name=998 显示为998
     * http://localhost:8080/hello/show18?name 显示为hello
     * @return
     */
    @RequestMapping("show18")
    public ModelAndView test18(@RequestParam(value="name",required=true,defaultValue="hello")String name){
        ModelAndView mv = new ModelAndView();
        mv.setViewName("hello2");
        mv.addObject("msg", "接收普通请求参数:" + name);
        return mv;
    }
}

10.AOP常用注解

@Aspect:作用是把当前类标识为一个切面供容器读取

@Pointcut:Pointcut是植入Advice的触发条件。每个Pointcut的定义包括2部分,一是表达式,二是方法签名。方法签名必须是 public及void型。可以将Pointcut中的方法看作是一个被Advice引用的助记符,因为表达式不直观,因此我们可以通过方法签名的方式为 此表达式命名。因此Pointcut中的方法只需要方法签名,而不需要在方法体内编写实际代码。

@Around:环绕增强,相当于MethodInterceptor

@AfterReturning:后置增强,相当于AfterReturningAdvice,方法正常退出时执行

@Before:标识一个前置增强方法,相当于BeforeAdvice的功能,相似功能的还有

@AfterThrowing:异常抛出增强,相当于ThrowsAdvice

@After: final增强,不管是抛出异常或者正常退出都会执行

示例:https://blog.csdn.net/fz13768884254/article/details/83538709

11.@ConfigurationProperties

https://blog.csdn.net/yusimiao/article/details/97622666

12.@ServletComponentScan

允许 Spring Boot 扫描和装载当前 包路径 和 子路径 下配置的 Servlet

13.@EnableWvc

允许 Spring Boot 配置 Spring MVC 相关自定义的属性,比如:拦截器、资源处理器、消息转换器等。

14.@RequestBody

@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);
GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交。
在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。


一个请求,只有一个RequestBody;一个请求,可以有多个RequestParam。


如果参数时放在请求体中,application/json传入后台的话,那么后台要用@RequestBody才能接收到;
如果不是放在请求体中的话,那么后台接收前台传过来的参数时,要用@RequestParam来接收,或者形参前什么也不写也能接收。


如果参数前写了@RequestParam(xxx),那么前端必须有对应的xxx名字才行(不管其是否有值,当然可以通过设置该注解的required属性来调节是否必须传),如果没有xxx名的话,那么请求会出错,报400。

https://blog.csdn.net/justry_deng/article/details/80972817

15.@JsonProperty

@JsonProperty注解的使用 - Mop猎人 - 博客园 (cnblogs.com)

16.@JsonFormat

@JsonFormat 实现原理 - 简书 (jianshu.com)

17.@SuppressWarnings

http://blog.sina.com.cn/s/blog_ad8b5870010166vt.html

18.@Qualifier

https://blog.csdn.net/qq_38289534/article/details/81666392

19.Spring缓存注解@Cacheable、@CacheEvict、@CachePut

https://www.cnblogs.com/fashflying/p/6908028.html

20.@PostContruct

https://blog.csdn.net/qq360694660/article/details/82877222

21.@DateTimeFormat 和 @JsonFormat 注解

https://blog.csdn.net/zhou520yue520/article/details/81348926

22.@DependsOn

https://blog.csdn.net/qq_40837310/article/details/106557588

23.@Qualifier

https://blog.csdn.net/qq_36567005/article/details/80611139

posted @ 2021-09-07 19:04  光一  阅读(133)  评论(0编辑  收藏  举报