Spring全家桶的常用注解详解

1. 基础复习

1.1 注解是什么?

注解是一种特殊的Java构造,也是一种引用数据类型,编译后也是生成.class文件。

自定义注解格式

[修饰符列表] @interface 注解类型名{

}

注解可以用在类,方法,字段,参数,变量,构造方法或包上;注解也可以用在注解上。

1.2 注解的组成部分

1.2.1 四个元注解

元注解:用来标注“注解类型”的注解

  1. @Target
    用来标注“被标注的注解”可以出现在哪些位置上。
    例如:@Target(ElementType.METHOD)
    表示“被标注的注解”只能出现在方法上。
    @Target(value = {ElementType.TYPE, ElementType.FIELD})
    表示“被标注的注解”可以出现在类上或者字段上

  2. @Retention
    用来标注“被注解的注解”最终保存在哪里。
    @Retention(RetentionPolicy.SOURCE):表示该注解只被保留在java源文件中。@Retention(RetentionPolicy.CLASS):表示该注解被保存在class文件中。@Retention(RetentionPolicy.RUNTIME):表示该注解被保存在class文件中,并且可以被反射机制所读取。
    这里注意:所有我们自定义(包括框架)的注解都要使用RetentionPolicy.RUNTIME,因为后面我们要通过反射去实现它的逻辑;一般由JDK自带的注解都是RetentionPolicy.SOURCE,因为它们的逻辑是JVM去实现的。

  3. @Inherited
    表明使用了@Inherited注解的注解,所标记的类的子类也会拥有这个注解

  4. @Document
    表明该注解标记的元素可以被Javadoc 或类似的工具文档化

1.2.2 注解内部属性

注解的代码块中可以有属性吗?
注解仅支持基本数据类型、字符串和枚举;这个枚举可以在注解内部定义。
注解中所有属性都定义为方法,可以提供默认值

例如这样的一个注解

@Target(value = {ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
    public enum Priority {LOW, MEDIUM, HIGH}
    public enum Status {STARTED, NOT_STARTED}
    String author() default "guaige";
    double price() default 300.0;
    Priority priority() default Priority.LOW;
    Status status() default Status.NOT_STARTED;
}

我们这么去使用它

@MyAnno(author = "laoba", priority = MyAnno.Priority.HIGH)
public void testMethod1() {

}

如果注解只有一个String类型属性,它的名字必须为value,我们在使用注解,给这个属性赋值时可以不用写字段名。

@interface Author{
	String value();
}

@Author("Yashwant")
public void someMethod() {

}

1.3 注解如何起作用?

首先我们看最常见的注解@Override的定义代码

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {

}

发现没有,这个注解里没有定义任何业务逻辑。
如果注解不包含逻辑,那么必须有其他地方能读取到我们使用了这个注解,并为其添加逻辑。

像@Override这样的标准注解,它的逻辑就是JVM所写的。

那我们自定义的注解呢?
还拿上面自定义的MyAnno注解举例。

@Target(value = {ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {

    public enum Priority {LOW, MEDIUM, HIGH}
    public enum Status {STARTED, NOT_STARTED}
    String author() default "guaige";
    double price() default 300.0;
    Priority priority() default Priority.LOW;
    Status status() default Status.NOT_STARTED;
    
}

我们需要使用反射,反射提供了Class,Method和Field对象,他们都有一个
getAnnotation()方法,返回的是指定的注解对象。
除了getAnnotation(),其余的还有
isAnnotationPresent():判断当前元素是否被指定注解修饰
getAnnotations():返回所有的注解(一个Annotation数组)

创建一个类,写两个方法,一个加上这个注解,一个不加。

public class MyTest {

    @MyAnno(author = "laoba", priority = MyAnno.Priority.HIGH)
    public void testMethod1() {

    }

    public void testMethod2() {
        
    }
}

写一个方法获取类中被@MyAnno注解的方法,拿到属性值。

class AnalysisAnno {

    public void customer() {
        Class<MyTest> myTestClass = MyTest.class;
        for (Method method : myTestClass.getMethods()) {
            MyAnno annotation = method.getAnnotation(MyAnno.class);
            if (annotation != null) {
//                使用注解的方法的名字
                System.out.println(method.getName());
//                属性值
                System.out.println(annotation.author());
                System.out.println(annotation.priority());
                System.out.println(annotation.price());
            }
        }
    }

    public static void main(String[] args) {
        AnalysisAnno analysisAnno = new AnalysisAnno();
        analysisAnno.customer();
    }
}

除了能拿到注解的属性值,当然还可以加入逻辑了。
比如我们想让上面被注解的这个方法,必须没有任何参数,否则报错。

    public void customer2() {
        Class<MyTest> myTestClass = MyTest.class;
        for (Method method : myTestClass.getMethods()) {
            MyAnno annotation = method.getAnnotation(MyAnno.class);
            if (annotation != null) {
                if (method.getParameterCount() != 0) {
                    throw new RuntimeException("被@MyAnno注解的方法不能有参数!");
                }
            }
        }
    }



2. 讲讲常用注解

2.1 Spring IOC相关

@Controller

放在控制层实现类的上面,创建控制器对象,注入到ioc容器中。

@Service

放在业务层实现类的上面,创建业务逻辑层对象,注入到ioc容器。

@Repository

放到dao层实现类上面,创建dao对象注入ioc容器。现在使用mybatis框架,dao对象是mybatis动态代理生成的,@Repository不再使用了。
不过依然可以和@Mapper注解一同使用。

@Component

放在类的上面,创建此类的对象,注入到ioc容器中,这个是针对普通的类的。

@Autowired

引用类型赋值,支持byName与byType的赋值方式,默认为byType。
该注解可以放在属性上或是方法上。

@Qualifer

引用类型赋值,使用byName方式赋值。
@Qualifer和@Autowired都是spring框架提供的

@Resource

是jdk提供的注解,引用类型的自动注入。
默认使用byName,如果byName失败,再使用byType注入。

@Bean

声明对象,将其注入到ioc容器。一般搭配@Configuration使用。

@Bean和@Autowired的区别:
@Bean是放入ioc容器,@Autowired是从ioc容器中拿出



2.2 Spring AOP相关

@Aspect

表示被注解的类是切面类。是一种AOP思想。

有五种常用的通知注解:

@Before:前置通知

@After:后置通知,无论方法什么情况都会执行,优先级高于@AfterReturning

@AfterReturning:后置通知,在方法完全执行结束后执行

@Around:环绕通知,一般在这里执行切点逻辑

@AfterThrowing:抛出异常通知


@Pointcut

定义一个切入点表达式。用法是将此注解写在一个方法之上,之后所有的切入点表达式都可以用这个方法代替。

@Aspect
public class MyTest {

    @Pointcut("execution(* *..service.*.*(..))")
    private void myPoint(){

    }

    @After("myPoint()")
    public String myDept() {
        return null;
    }
    
}



2.3 Spring其他

@Value

基本数据类型赋值(八大基本数据类型及其包装类,以及String)
可以数据写死赋值

@Value("李四") 
private String name

也可以读配置文件(properties或yml)赋值

@Value("${server.port}")
private Integer port
@PropertySource

指定properties文件的位置
读取properties属性配置文件,可以实现外部化配置。
一般搭配@Value一起使用。

@ImportResource

不常用。作用是导入其他的xml配置文件。

@Transactional

在业务方法上使用@Transactional,使方法有事务功能

@EnableTransactionManager

在主启动类上加上这个注解,让上面的@Transactional注解生效。


2.4 Mybatis相关

@Mapper

放在mapper接口的上面,让mybatis找到mapper接口,通过动态代理创建其对象。

@MapperScan

放在主类(Application)上面,指定扫描的包,将这个包中所有接口都创建代理对象,注入ioc容器。

@Param

在mapper接口方法的形参前面,作为其命名参数在mapper的xml文件中使用。


2.5 SpringMVC相关

@ResponseBody

放在方法的上面,表示方法的返回值是数据。
将Java对象转换为json数据返回给前端。

@RequestBody

把post请求的请求体里的json数据读取为Java对象进行使用。

@RequestParam

常用于get请求,表示这个参数必须要有值,否则报错(400)
也可以用于指定收参数的名字

@GetMapping("/detail")
public String Detail(@RequestParam("id") String userId) {
    return null;
}

例如这里,前端给我们传的是id,我们通过@RequestParam接收了id,但是方法形参可以任意,比如我们这里写的是userId

@RequestMapping

配置请求路径,可以放到Controller类上面,或者Controller类的接口方法上。


2.6 SpringBoot相关

@Configuration

放在一个类的上面,表示这个类作为配置文件使用。

@SpringBootApplication

复合注解,由
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
组成

@SpringBootConfiguration:使用此注解标注的类,可以作为配置文件使用,可以使用@Bean对象注入到容器。

@EnableAutoConfiguration:启用自动配置,把Java对象配置好,注入到ioc容器中。

@ComponentScan:包扫描器,找到注解,根据注解的功能创建对象、给属性赋值等等。
默认扫描的包:@ComponentScan注解的类 所在的包和子包。


@ConfigurationProperties

把配置文件的数据映射为Java对象,直接注入给类中属性。(不常用)

@PathVariable

从REST风格的url中获取数据,例如

@GetMapping("/detail/{id}")
public String detail(@PathVariable("id") String id) {
    return null;
}
@GetMapping

@RequestMapping(method=RequestMethod.GET)

@PostMapping

@RequestMapping(method=RequestMethod.POST)

@PutMapping

@RequestMapping(method=RequestMethod.PUT)

@DeleteMapping

@RequestMapping(method=RequestMethod.DELETE)

@RestController

复合注解,是@Controller 和@ResponseBody组合。
在类的上面使用@RestController,表示所有方法上都加上了@ResponseBody

@Valid

这个注解通常用于post请求,用一个类接收前端的json参数时,对参数进行数据验证。参数前有了这个注解,接收参数的RO类里的注解就可以生效。

常用的几个做参数验证的注解

@NotBlank:不能为空或空字符串
@NotNull:不能为空值,可用在所有类型上面
@Min(value) :被注解的字段必须是数字,必须大于指定的最小值
@Max(value) :被注解的字段必须是数字,必须小于指定的最大值
@Size(min,max) :被注解的字段必须是字符串、集合或数组,长度在min和max之间
@Length(min,max) :被注解的字符串的长度在min与max之间。
@NotEmpty:用在String或集合上面,被注解的字段不为null且大小(长度)不为0
@Range(min,max) :被注解的字段必须是数字,值在min与max之间。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值