spring 常用注解
Configuration 配置类 相关注解
-
@Configuration:标注在类上,声明该类为 Spring 配置类
Spring 在启动的时候会自动扫描并加载所有配置类,配置 Spring 容器(应用上下文),将配置类中的 Bean 放入容器管理
-
@Bean:标注在 Spring 配置类中的方法上,注册 bean 对象到 IOC 容器
- name 属性:给生成的bean指定唯一标志
在 Spring 容器启动的时候,自动的扫描并执行所有配置了 @Bean 的方法,并将返回值存入Spring容器
注意:
- 被标注的方法,需要返回某个实例
- 被标注的方法,可以配置依赖的属性参数,Spring 会自动从容器中获取到依赖的对象,自动调用方法
-
@Primary:在某些情况下,需要注册多个相同类型的 bean,此时可以使用 @Primary 来赋予某个 bean 更高的优先级
-
@***ponentScan:开启包扫描(Spring IOC注解支持),默认扫描当前包及子包下所有类
- basePackage 属性:指定扫描的包路径。可以减少加载时间
如果扫描到类上有 IOC 注解,就会把当前类交给 IOC 容器管理,当容器启动时,自动创建对象存入容器
如果扫描到属性上有 DI 注解,则依据依赖注入的规则,给属性注入值
-
@PropertySource:加载本地 properties 文件交给 Spring 容器管理
- value 属性:指定本地 properties 路径
-
@Import:在一个配置类中导入其它配置类的内容
- value 属性:指定其他的配置类的 class 类路径
Spring 支持多配置类(配置类的模块),若配置类臃肿,可以拆分配置类,然后在主配置类中引入子配置类(子配置类上不用配置注解)
-
@Conditional
@Condition 是在 Spring 4.0 增加的条件判断功能,通过这个可以功能可以实现选择性的创建 Bean 操作
@Conditional 标注在配置类上或配置类的方法上,和 @Configuration 配合使用,@Conditional 指定的条件成立,配置类里面的内容才生效
SpringBoot常用条件注解:
-
@ConditionalOnBean:容器中存在指定Bean
-
@ConditionalOnMissingBean :容器中不存在指定Bean
- value 属性:作为条件的类的Class对象数组
- type 属性:作为条件的类的 Name 数组(Class.getName())
- annotation 属性:bean 上拥有指定的注解数组
- name 属性:spring 容器中 bean 的名字
-
@ConditionalOnProperty:系统中指定的属性是否有指定的值
-
value / name 属性:配置名称,完整名称或部分名称(name 与 value 不可同时使用)
可以与 prefix 配合使用
可以传数组支持多个条件的组合(多个条件逻辑与)
若想使用多个条件逻辑或:
-
方式1:使用 @ConditionalOnExpression 写“逻辑或”表达式
@ConditionalOnExpression("${app.dictionary:false} || ${app.all:false}")
-
方式2:使用 @ConditionalOnExpression 写“默认值”嵌套表达式
@ConditionalOnExpression("${app.dictionary:${app.all:false}}")
-
-
prefix 属性:配置前缀(可有可无)
-
havingValue 属性:对比值,与 name 组合使用,该值与配置中值相同,则配置生效,不相同则配置不生效
-
matchIfMissing 属性:缺少该配置属性时是否可以加载。
缺少配置时, true: 正常加载,false:报错。默认为 false
-
-
@ConditionalOnClass :系统中有指定的类
-
@ConditionalOnMissingClass: 系统中没有指定的类
-
@ConditionalOnExpression :满足SpEL表达式指定
-
@ConditionalOnSingleCandidate :容器中只有一个指定的Bean,或者这个Bean是首选Bean
-
@ConditionalOnResource :类路径下是否存在指定资源文件
-
@ConditionalOnWebApplication :当前是web环境
-
@ConditionalOnNotWebApplication :当前不是web环境
-
@ConditionalOnJava:系统的java版本是否符合要求
-
IOC(容器)相关注解
- @Controller:一般标注在表现层(web层)的类上
- @Service: 一般标注在业务层(service层)的类上
- @Repository: 一般标注在持久层(dao层)的类上
- @***ponent:组件, 非三层模式范围的类上使用
说明:
- 标注在想要被 IOC 容器管理的类上,表明创建对象交给容器管理
- 当 Spring 容器启动时,根据包扫描配置自动的扫描到 IOC 注解,反射创建注解标注的对象,存入容器,委托容器管理
- 默认存入容器的 id(唯一标识)为当前类名首字母小写。可以通过 value 属性自定义存入容器中对象的 id
@Import 注解:把类导入 Spring IOC容器
有多种方式能让类加 IOC容器管理,如@Bean、@***ponent等,@Import 是另外一种方式,更加快捷。
支持三种方式:
- 带有 @Configuration 的配置类(4.2版本之前只可以导入配置类,4.2版本之后 也可以导入普通类)
- ImportSelector 的实现
- ImportBeanDefinitionRegistrar 的实现
主要用法:
-
直接填 class 数组方式
@Configuration @Import({User.class}) // 大括号中可以添加多个类,使用逗号分隔,例如 {User.class,UserInfo.class} public class UserConfig {}
-
ImportSelector 方式(Spring Boot 底层采用比较得多的方式)
// 自定义ImportSelector public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { // 返回的是需要加载的类名数组 注意这里需要的是类的全路径 return new String[]{"***.itheima.redis.entity.User"}; } }
@Configuration @Import(MyImportSelector.class) public class UserConfig {}
-
ImportBeanDefinitionRegistrar 方式
这种方式和 ImportSelector 方式类似,不过这种方式可以自定义Bean在容器中的名称
// 自定义ImportBeanDefinitionRegistrar public class TestImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) { RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TestD.class); //自定义注册bean registry.registerBeanDefinition("testD1111",rootBeanDefinition); } }
@Import({TestImportBeanDefinitionRegistrar.class}) @Configuration public class ImportConfig {}
- 注意:三种用法方式都可在一个@Import中使用,需要注意的是class 数组方式、ImportSelector 方式在IOC容器中bean名称是类的全限定类名,而ImportBeanDefinitionRegistrar 方式是自定义的名称
DI(依赖注入)相关注解
DI 注解都相当于直接给属性赋值,而无需借助于 set 方法或构造方法
-
@Autowired
使用方式1:标注在属性上
- 直接给属性赋值(通过 @Autowired 依赖注入,不需要配置 set 方法)
- 默认是通过 by Type(根据类型,即接口类型)的形式从 IOC 容器中查找对象并给属性注入值
- 如果 IOC 容器中存在多个与属性同类型的对象(一个接口有多个实现类),
- 默认是按照属性名(by Name)作为唯一标志从容器中查找对象并给属性注入值
- 可以和 @Qualifier 注解共同使用,指定唯一标志从容器中查找对象并给属性注入值
- value:指定 IOC 容器中对象唯一标志(id)
使用方式2:标注在方法上
- 表示自动执行当前方法,如果方法有参数,会自动从 IOC 容器中寻找同类型的对象给参数传值
- 也可以在参数上添加 @Qualifier(“IOC容器中对象id”) 注解按照名称寻找对象给参数传值
使用注意事项
-
只能在被 Spring 容器托管(标注了 @Controller 等 IOC 注解)的类中使用 @Autowired 注解
-
自动注入与权限修饰符无关,即使是 private 修饰的字段也可以自动注入
-
默认情况下,使用 @Autowired 注解进行自动注入的属性一定要被装配( Spring 容器托管)
如果在容器中找不到该类型的bean 进行注入,就会报错
如果允许不被装配,可以将 @Autowired 的 required 属性为 false
-
@Autowired 是基于类型的注入,如果当前类型属性在容器中只有一个 Bean,那么属性名不限制,但一般建议遵循类名首字母小写的规则
-
如果当前属性类型在容器中有个多个Bean,那么必须要通过属性名或者同时标注 @Qualifier 注解指定 Bean name
-
@Qualifier:当有多个同一类型的 Bean 时,可以用@Qualifier(“name”) 来指定。只能与@Autowired配合使用
-
@value:可用于简单数据类型的注入,但通常不这么使用。标注在属性上。
一般用于解析 properties 配置文件或注册中心的配置文件中的内容
- 根据 key 值获取对应的 value ,语法规则: @Value(“${key}”)
- 使用步骤:
- properties 配置文件交给 Spring 容器管理
- 通过 @Value,从容器中得到配置项,并注入
-
@Reource(了解)
jdk 提供的依赖注入的注解,此注解在 jdk9 及以上版本已经移除
- 只能标注在被 Spring 容器托管的类的属性上
- 表示先按照属性名匹配 IOC 容器中对象 id 给属性注入值【by name】
- 若没有成功,会继续根据当前属性的类型匹配 IOC 容器中同类型对象来注入值 【by type】
- 若指定了 name 属性 @Resource(name = “对象id”),则只能按照对象 id 注入值
AOP(方法增强)相关注解
-
@EnableAspectJAutoProxy:标注在配置类上,开启 aop 注解支持
-
@Aspect:标注在自定义类上,声明切面类
注意:该切面类同时需要标注 IOC注解(@***ponent),交给 Spring 容器管理
-
在切面类中的通知(增强)方法上通过注解配置通知类型:
- @Before:前置通知
- @AfterReturning: 后置通知
- @AfterThrowing:异常通知
- @After:最终通知
- @Around:环绕通知
通知注解的属性:
-
value / argNames 属性:切入点表达式 或 被 @Pointcut 标注的方法名()
@Around("pt()") public Object around(ProceedingJoinPoint pjp)
-
@Pointcut:标注在切面类中的空的方法上,抽取公共的切入点表达式
- value / argNames 属性:切入点表达式
- 通知注解配置 方法名() 即可引入公共的切入点表达式
@Pointcut(value="execution(* ***.test.service.impl.*.*(..))") public void pt() {}
事务管理 相关注解
-
@EnableTransactionManagement:标注在配置类上,开启事务注解支持
-
@Transactional:配置事务
常用属性:
-
rollbackFor 属性:设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚
-
指定单一异常类:@Transactional(rollbackFor=Exception.class)
-
指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})
-
-
readOnly 属性:是否只读事务 ( true | false(默认值) )
-
propagation 属性:事务传播行为 ( SUPPORTS | REQUIRED(默认值) )
-
transactionManager 属性:多个事务管理器托管在 Spring 容器中时,指定事务管理器的 bean 名称
-
isolation 属性:设置底层数据库的事务隔离级别,事务隔离级别用于处理多事务并发的情况
通常使用数据库的默认隔离级别即可,基本不需要进行设置
-
noRollbackFor 属性:设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚
标注位置说明:
- 标注在类上:该类中所有方法都具有相同的事务配置
- 标注在方法上:该方法具有事务配置
- 同时标注在类上和方法上:就近原则(方法上的事务配置生效)
-
生命周期 相关注解
-
@Scope : 在类上配置对象的作用域
通过 value 属性指定作用范围(singleton|prototype),默认为 singleton(单例)
-
@PostConstruct : 配置对象创建后的触发动作
当对象创建完成之后,自动执行的方法
-
@PreDestroy :配置对象销毁前的触发动作(仅在 Scope = singleton 时有效)
容器关闭,对象销毁之前执行的方法
单元测试 相关注解
-
@RunWith:设置单元测试的运行器,通过 value 属性指定单元测试运行环境
- SpringJUnit4ClassRunner.class:Spring 测试环境
- SpringRunner.class:Spring 测试环境
注:
-
SpringRunner extends SpringJUnit4ClassRunner.class
-
使用上 JUnit4.12 或更高版本以上 SpringRunner、SpringJUnit4ClassRunner 都可以使用
但是推荐使用 SpringRunner,final类型,安全
-
JUnit4.12 以下版本就只能使用 SpringJUnit4ClassRunner
-
@ContextConfiguration:指定容器的配置信息
- localtions 属性:配置文件路径
- classes 属性:配置类
异步调用 相关注解
-
@EnableAsync:标注在启动类或配置类上,使 @Async 注解生效
-
@Async:标注在一个异步切入点方法上,表示该方法异步调用
此方法被调用时,会从 Spring 自带的线程池中取一个线程执行这个方法,而不是用 web 线程池中的线程,这样 web 线程池中的线程就可以用来继续服务其他新的客户端请求
注意:
-
该方法所在类需被 Spring 容器管理
-
所修饰的函数不要定义为 static 类型,否则异步调用不会生效
-
返回值:若不需要返回值,直接void;需要返回值用 AsyncResult 或者 ***pletableFuture
-
可指定自定义执行器(线程池),例如:@Async(“otherExecutor”)(通过 @bean 自定义一个线程池 )
-
若在 Spring 中单独使用 @Async 注解,必须指定执行器(即配置线程池),否则会报错:
org.springframework.aop.interceptor.AsyncExecutionAspectSupport getDefaultExecutor
-
而在 SpringBoot 当中由于自动配置,直接默认配置了一个 SimpleAsyncTaskExecutor 线程池
-
-
@Async 标注的方法必须是不同类间调用: A类 ==> B类.C方法()(@Async标注在B类的C方法上)
如果在同一个类中调用,会变同步执行,例如:A类.B() ==> A类.@Async C方法()
原因是:底层实现是代理对注解扫描实现的,B方法上没有注解,没有生成相应的代理类。(当然把@Async加到类上也能解决,但所有方法都异步了,一般不这么用!)
-
Spring MVC 常用注解
Controller 相关
-
@RequestMapping:用于建立请求URL和处理方法之间的映射关系,也可以通过它的属性对请求做出各种限制
可标注在类、方法上,若用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
属性:
- value / path 属性:指定映射的请求地址,指定的地址可以是URI Template 模式
- method 属性:指定请求的 method 类型, GET、POST、PUT、DELETE等,示例:RequestMethod.post
- params 属性:指定 request 中必须包含的参数,若请求没有携带指定参数,则抛出异常
- headers 属性:指定 request 中必须包含某些指定的header值,才能让该方法处理请求。
- consumes 属性:指定处理请求的提交内容类型(Content-Type),如application/json,text/html;
- produces 属性:指定返回的内容类型,仅当request请求头中的(A***ept)类型中包含该指定类型才返回
-
@RequestParam:标注在 Controller 方法参数之前,用于对请求中 url 传入的普通参数做一些限制
支持三个属性:
- value / name 属性:默认属性,用于绑定请求传入的参数名称。一般在请求传参和 Controller 方法入参不一致时使用
-
required 属性:用于指定此参数是否必传
- @RequestParam 修饰的参数默认必须传值,可以用 required = false 来指定非必传值
- defaultValue 属性:指定参数默认值(当参数为非必传参数且请求没有传入该参数时,使用默认值)
若不加 @RequestParam 注解:
- 前端的参数名需要和后端控制器的变量名保持一致才能生效
- 参数为非必传
-
@PathVariable:映射 URL 绑定的占位符
带占位符的 URL是 Spring3.0 新增的功能
URL中的 {xxx} 占位符参数可以通过 @PathVariable(“xxx”) 绑定到控制器处理方法的入参中
@RequestMapping("/testPathVariable/{id}") public String testPathVariable(@PathVariable("id") Integer id) { System.out.println("testPathVariable:"+id); return SU***ESS; }
全局数据处理(@ControllerAdvice)
-
@ControllerAdvice:定义 Controller 层全局数据处理类。作用在注解了 @RequestMapping 的控制器方法上
包含注解 @***ponent,可以被扫描到
一般和以下注解搭配使用
- @ExceptionHandler(异常处理)
- @ModelAttribute(数据绑定)
- @InitBinder(数据预处理)
- **注意:**这三个注解都可以在普通的 Controller 类上使用,ControllerAdvice只是作用范围可以自定义(默认全部)
支持属性:
-
value / basePackages 属性: 数组类型,指定一个或多个包,用来指定可以作用的基包
即将对指定的包下面的 Controller 及其子包下面的 Controller 起作用
若不指定,默认所有被扫描的包
-
basePackageClasses 属性: 是 basePackages 的一种变形, 数组类型,指定一个或多个 Controller 类,这些类所属的包及其子包下的所有 Controller 都被该 @ControllerAdvice 管理
-
assignableTypes 属性:数组类型,用来指定具体的 Controller 类型,它可以是一个共同的接口或父类等
-
annotations 属性: 指定一个或多个注解,被这些注解所标记的 Controller 会被该 @ControllerAdvice 管理
-
@RestControllerAdvice:定义 Controller 层全局数据处理类
组合注解,由注解 @ControllerAdvice、@ResponseBody 组成
-
@ExceptionHandler:用于捕获 Controller 中抛出的不同类型的异常
常与 @ControllerAdvice 注解搭配使用,从而实现全局异常处理
-
@ModelAttribute:被其标注的方法会在执行目标 Controller 方法之前执行
常与 @ControllerAdvice 注解配合使用,可以让全局的 @RequestMapping 方法都能获得在此处设置的键值对
-
@InitBinder:用来设置 WebDataBinder,进行请求数据预处理
Spring Boot 常用注解
-
@SpringBootApplication:组合注解,通常标注在启动类上
-
@Configuration:声明该类为 Spring 配置类,把该类中定义的 Bean 加载到 Spring 容器中
-
@EnableAutoConfiguration:自动加载所有符合条件的 @Configuration 配置到当前 SpringBoot 环境
例如:若添加了 spring-boot-starter-web 依赖,由于其使用了 Tomcat 和 Spring MVC,所以 auto-configuration 将假定正在开发一个 web应用,并对 Spring 进行相应地设置。
-
@***ponentScan:开启包扫描(IOC注解支持),默认扫描当前包及子包下所有类
可以通过 basePackage 属性指定扫描的包路径,以减少加载时间
-
-
@SpringBootTest:配置文件属性的读取。在运行 SpringBoot 为基础的测试类上标注
- 当定义没有特定的 @ContextConfiguration(loader=…) 时,使用 SpringBootContextLoader 作为默认的 ContextLoader
- 当不使用嵌套 @Configuration 时,自动搜索@SpringBootConfiguration,并且没有指定显式的类
- 允许使用 properties 属性定义自定义环境属性
- 为不同的webEnvironment模式提供支持,包括启动一个完全运行的 web 服务器,监听一个已定义的或随机的端口。
- 注册一个 TestRestTemplate 或 WebTestClient bean,用于在web测试中使用完全运行的web服务器
-
@ConfigurationProperties:用于自动配置绑定
支持属性:
- value / prefix 属性:配置文件配置项的前缀
- ignoreInvalidFields 属性:默认为 false,值类型不匹配将会爆出异常
- ignoreUnknownFields 属性:默认为 true,忽略掉对象中未知的字段
用法1:标注在类上,转换配置文件配置项为 bean 对象
- 注意:
- 需要将标注了 @ConfigurationProperties 注解的类注册到spring容器中,方式有两种:
- 方式1:在标注了@ConfigurationProperties 注解的类上使用 @***po*** 等 IOC 注解
- 方式2:在标注了@***po*** 等 IOC 注解的类上或配置类上标注 @EnableConfigurationProperties(bean类名.class)
- 需要有无参构造方法、getter和setter方法
- 需要将标注了 @ConfigurationProperties 注解的类注册到spring容器中,方式有两种:
@Data @AllArgsConstructor @NoArgsConstructor @***ponent @ConfigurationProperties(prefix = "app.mycar") public class Car { private int price; private String brand; }
@Configuration @EnableConfigurationProperties(Car.class) public class Config { }
用法2:标注在配置类的方法上,搭配 @bean 使用,绑定第三方属性
@Configuration public class DbConfig { @Bean @ConfigurationProperties(prefix = "spring.datasource.druid") public DataSource datasource(){ return new DruidDataSource(); } }
-
@EnableConfigurationProperties:使 @ConfigurationProperties 注解生效,并自动将这个类注入到 IOC 容器中
标注在有 @***po*** 等 IOC 注解的类上或配置类上
支持属性:
- value 属性:Class<?>[] 数组,即标注了 @ConfigurationProperties 注解的类的Class数组
Spring Cloud 常用注解
服务注册 / 服务发现 / 配置中心
-
@EnableEurekaClient:开启使用服务注册和服务发现
基于spring-cloud-***flix,若选用的注册中心是 eureka,推荐使用该注解
-
@EnableDiscoveryClient:开启使用服务注册和服务发现
基于spring-cloud-***mons,若是其他的注册中心,推荐使用该注解
-
@EnableEurekaServer:在启动类或配置类标注,标识该服务为eureka服务端
-
@EnableConfigServer:在启动类或配置类标注,标识该服务为服务中心服务端
-
@RefreshScope:标注在类上,自动刷新从配置中心获取的数据
只有添加此注解,配置中心数据刷新时,该类的对象会自动重新加载,自动更新数据注入 @value
Feign 组件
-
@EnableFeignClients:开启Feign注解。标注在启动类或配置类上
项目启动时,就会启动一个 FeignSterter 组件,这个组件会对项目中使用 @FeignClient 的类创建代理对象
-
@FeignClient:声明这是一个 Feign客户端,同时通过 name / value 属性指定服务名称
-
只能标注在远程服务调用的接口上
(FeignClient注解被 @Target(ElementType.TYPE) 修饰,表示 FeignClient 注解的作用目标在接口上)
-
当 SpringCloud 扫描到被 @FeignClient 标识的接口时,底层会为其创建实现类代理对象(jdk代理),并交给 spring容器管理(注册IOC容器);创建出来Bean对象的名字由注解的name或value属性指定,若对同一个服务创建两个远端服务调用接口时会报错
-
接口中定义的方法,完全采用 SpringMVC 的注解,Feign 会根据注解生成 URL,并访问获取结果
-
服务的启动类或配置类需要标注 @EnableFeignClients 注解才能使 Fegin 生效
@FeignClient注解的常用属性如下:
-
name / value 属性:指定FeignClient的名称,如果项目使用了Ribbon(注册中心),name属性会作为微服务的名称,用于服务发现
-
url 属性:一般用于调试,可以手动指定@FeignClient调用的地址。默认为空
-
url可以从配置文件获取,如果有则通过url调用,没有则根据服务名调用。
格式为
url = "${xxx.xxx.xxx: }"
-
-
configuration 属性:Feign配置类,可以自定义 Feign 的 Encoder、Decoder、LogLevel、Contract,可以为每一个feign client 指定不同的配置
-
fallback 属性:定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口
-
fallbackFactory 属性:工厂类,用于生成fallback类示例,通过这个属性可以实现每个接口通用的容错逻辑,减少重复的代码
-
path 属性:定义当前FeignClient的统一前缀,当项目中配置了server.context-path, server.servlet-path时使用
-
decode404 属性:当发生http 404错误时,如果该字段位 true,会调用 decoder 进行解码,否则抛出 FeignException
-
其他注解
-
@LoadBalanced:开启 Ribbon 负载均衡功能
对 RestTemplate 添加一个LoadBalancerClient,通过 Ribbon 以实现客户端负载均衡
- 标注在 RestTemplate 对象上,由 SpringCloud 的 ***mons 模块提供
原理:当使用 RestTemplate 对象调用服务时,系统底层会对服务进行拦截,拦截到 url 后,会基于 url 的服务名获取具体的服务实例,然后基于服务实例重构 url,再基于新的 url 进行服务调用
-
@EnableCircuitBreaker:开启断路器功能
-
@EnableHystrixDashboard:在启动类或配置类标注,标识该服务为Hystrix-Dashboard服务(仪表盘),监控服务器的流量
-
@EnableTurbine:在启动类或配置类标注,标识该服务为Turbine服务,同时监控多个服务器流量
-
@EnableZuulProxy:在主启动类或配置类使用此注解,标识该服务为Zuul网关服务
lombok 常用注解
-
@Data:注解在类上;提供 getter、setter 、equals、canEqual、hashCode、toString 方法
-
@Setter:注解在属性上;为属性提供 setter 方法
-
@Getter:注解在属性上;为属性提供 getter 方法
-
@NoArgsConstructor:注解在类上;为类提供一个无参的构造方法
-
@AllArgsConstructor:注解在类上;为类提供一个全参的构造方法
-
@EqualsAndHashCode:实现 equals() 方法和 hashCode() 方法
-
@ToString:实现 toString() 方法
-
@Slf4j:注解在类上;为类提供一个 属性名为 log 的 log4j 日志对象
slf4j 是一个适配器,当应用更换了一个日志源后,不需要更改代码
-
@Log4j:注解在类上;为类提供一个 属性名为 log 的日志对象
log4j是真正实现日志功能的产品
-
@Cleanup:关闭流
-
@Synchronized:对象同步
-
@SneakyThrows:抛出异常