注解
- 简介
- 索引
- SpringBoot篇
- @RequestParam
- @DateTimeFormat
- @RequestBody
- @PathVariable
- @ResponseBody
- @Component, @Controller, @Service, @Repository
- @ComponentScan
- @Autowired, @Primary, @Qualifier, @Resource
- @Value
- @ConfigurationProperties
- @WebFilter, @ServletComponentScan
- @Configuration
- @RestControllerAdvice, @ExceptionHandler
- @Transactional, @EnableTransactionManagement
- @Bean
- @Configuration
- @Import
- @Enable XXXX
- @Conditional
- Spring Cache
- Spring Task
- aspect篇
- Lombok篇
- Mybatis篇
- 日志篇
- knife4j篇
- Jackson Databind篇
简介
这篇文章主要用于记录我在学习中所遇见的以及学习的各类注解,为了防止自己忘记,特地写文章记录,并且提供给和我一样的正在学习中的小伙伴。
我将按照我学习的顺序来。
本人刚开始学习,仍为小白,若发现文章有什么错误或者是缺漏,可私信或者是评论,谢谢各位指教!
索引
SpringBoot篇
@RequestParam
@RequestParam的用法有很多,可以完成映射参数名等等。
-
在springboot的controller层当中,我们需要接受来自于前端的的参数,当参数名与形参变量名相同时,定义形参即可直接接收参数。如果方法形参名称与请求参数名称不匹配,即可使用@RequestParam注解完成映射。
前端传递的参数:
参数名称 示例 name Tom 后端接收的参数:
public void myName(@RequestParam(value = "name") String myName){ }
如此即可接收到name参数。值得一提的是,在此注解中有一个属性required,默认为true,意思是若前端并未传递此参数,则会报错。
-
当前端传入的为集合参数时,我们可以使用数组或者是集合来接收。
当形参类型为数组时,我们无需使用此注解,请求参数名与形参数组变量名相同,可直接使用数组。
当形参类型为集合时,我们需要使用@RequestParam注解。
参数名称 示例 ids 1,2,3 public void ids1(Integer[] ids){ } public void ids2(@RequestParam List<Integer> ids){ }
@DateTimeFormat
使用@DateTimeFormat注解完成日期参数格式转换
public void time(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime time){
}
@RequestBody
@RequestBody用来标识实体类对象接收参数
前端传递的为json参数,我们可以定义实体类来接收,但是需要使用@RequestBody注解标识。
前端传递的参数:
参数名称 | 示例 |
---|---|
name | Tom |
age | 18 |
后端接收的参数:
public class User{
private String name;
private Integer age;
}
public void aaa(@RequestBody User user){
}
@PathVariable
获取路径参数
前端通过请求URL直接传递参数,使用{…}来标识路径参数,需要使用@PathVariable获取路径参数。
@RequestMapping("/user/{id}")
public void bbb(@PathVariable Integer id){
}
@ResponseBody
将实体类对象转换为JSON格式字符串,来统一响应结果。
不常使用,因为在@Controller注解中包含了此注解。
@Component, @Controller, @Service, @Repository
以上均为声明Bean的注解
@Component为声明bean的基础注解
@Controller标注在控制器上,其源码如下
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
@Service标注在业务类上,其源码如下
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
@Repository标注在数据访问层上,其源码如下
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
后三个注解的子注解均有@Component,因此也可以用来声明bean。
声明bean时,可通过value属性指定名字,Bean对象默认名字为首字母小写,例如UserController类的Bean对象名字为userController。
在SpringBoot中,声明控制器只能使用@Controller
@ComponentScan
扫描Bean组件的注解
上面声明Bean注解的四大注解,如果想要生效,还需要被@ComponentScan注解扫描到。
那为什么我们初识SpringBoot时并未使用这个注解呢?
因为@ComponentScan注解被包含在@SpringBootApplication注解中,@SpringBootApplication注解用于标识项目的启动类上,在SpringBoot项目的启动类我们可以看到这个注解。
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
此为@SpringBootApplicaiton的源代码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
...................
}
我们可以看到@ComponentScan默认扫描为启动类所在包及其子包。
若我们想要更改扫描范围,需在启动类上加上@ComponentScan注解,并指定要扫描的范围。
@Autowired, @Primary, @Qualifier, @Resource
此类注解都用于Bean的注入
@Autowired注解为自动注入Bean,默认按照类型进行注入,我们平时一般都是用此注解,但是如果存在多个相同类型的bean,将会报错。因此我们需要后三个注解来帮助我们解决这个问题。
@Primary用在bean的类上,用来设置注入的优先级,加上了此注解的类将会首先被注入。
package com.example.firstDemo
@Component
@Primary
public class A{
}
package com.example.secondDemo
@Component
public class A{
}
public class B{
@Autowired
private A a;
}
注入的为firstDemo包下的A类。
@Qualifier用在注入对象上,可根据名称注入。
package com.example.firstDemo
@Component(value = "a1")
public class A{
}
package com.example.secondDemo
@Component(value = "a2")
public class A{
}
public class B{
@Autowired
@Qualifier("a2")
private A a;
}
注入的为seconfDemo包下的A类。
@Resource用在对象注入上,使用方式为根据名称注入。
package com.example.firstDemo
@Component(value = "a1")
public class A{
}
package com.example.secondDemo
@Component(value = "a2")
public class A{
}
public class B{
@Resource(name = "a1")
private A a;
}
注入的为firstDemo包下的A类。
注意:
- @Autowired是spring框架提供,而@Resource是JDK提供。
- @Autowired按照类型进行注入,@Resource按照名称进行注入。
@Value
该注解用于参数配置。
若将参数配置在类中,不便维护和管理。因此可将参数在外部配置,并通过@Value注解引入。
com:
example:
handsomeMan: me
@Component
public class HandsomeMan{
@Value("${com.example.handsomeMan}")
private String handsomeMan;
}
这样handsomeMan就是me了。
@ConfigurationProperties
批量引入配置
若需要引入的配置过多时,一个一个指定@Value显得太过于繁琐,因此我们需要@ConfigurationProperties来批量引入。
com:
example:
handsomeMan: me
smartMan: me
greatMan: me
@Component
@ConfigurationProperties(prexit = "com.example")
public class Man{
private String handsomeMan;
private String smartMan;
private String greatMan;
}
这样三个都是me了。
@WebFilter, @ServletComponentScan
@WebFilter注解加在Filter类上,用来标识这是一个过滤器,并且配置拦截资源的路径。
若想实现过滤功能,还需在启动类加上@ServletComponentScan
@WebFilter(urlPatterns = "/com/example/*", filterName = "loginFilter")
public class LoginFilter implements Filter{
}
@Configuration
加在类上,标识此类为一个配置类。
@RestControllerAdvice, @ExceptionHandler
定义全局异常处理器。
一个项目中可能一次业务的处理可能涉及到多个不同的接口,那么当一个接口出现异常时,程序会停止运行,因此需要将异常抛出,交给最顶层处理,即全局异常处理器。
定义全局异常处理器需定义一个类,类上加@RestControllerAdvice注解,方法上加@ExceptionHandler注解指定异常处理的类型。
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler
public Result exceptionHandler(Exception ex){
log.error("异常信息:{}", ex.getMessage());
return Result.error(ex.getMessage());
}
@ExceptionHandler注解未指定即代表处理所有类型的异常。
@Transactional, @EnableTransactionManagement
@Transactional注解标识在需要事务的方法上。
@EnableTransactionManagement注解标识在启动类上用来开启注解方式的事务管理。
将当前方法交给spring进行事务管理,方法执行前,开启事务;成功执行完毕,提交事务;出现异常,回滚事务。
@Transactional注解本人一般用于Service层实现类上,在对多表进行操作时,加上此注解,以免表数据出错。
@Transactional注解含有许多的属性,我们熟悉的有rollbackFor、propagation等等。
一、rollbackFor
默认情况下,只有出现RuntimeException即运行期异常才回滚。rollbackFor属性可用来控制抛出什么异常时回滚。
二、propagation
该属性可以控制事务的传播行为,即当一个事务面对另一个事务时,它的处理行为。
行为 | 描述 |
---|---|
REQUIRED(默认) | 需要事务,有则加入,无则创建 |
REQUIRED_NEW | 无论有无,总是创建 |
SUPPORTS | 有则加入,无则在无事务状态运行 |
NOT_SUPPORTED | 如果存在事务,则挂起该事务 |
MANDATORY | 必须有事务,否则抛出异常 |
NEVER | 必须没事务,否则抛出异常 |
@Bean
管理第三方的bean。
如果要管理的bean来自第三方,则需要用到@Bean注解。
@Configuration
public class WebSocketConfiguration {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
例如注册WebSocket需要使用到@Bean注解。
若要管理第三方bean,建议对bean进行集中配置,可通过@Configuration注解声明一个配置类。
@Configuration
声明一个配置类。
@Import
@Import实现导入功能
@Import注解可将一个类导入至IOC容器当中。
1、@Import一个普通类 spring会将该类加载到spring容器中
2、@Import一个类,该类实现了ImportBeanDefinitionRegistrar接口,在重写的registerBeanDefinitions方法里面,能拿到BeanDefinitionRegistry bd的注册器,能手工往beanDefinitionMap中注册 beanDefinition
3、@Import一个类 该类实现了ImportSelector 重写selectImports方法该方法返回了String[]数组的对象,数组里面的类都会注入到spring容器当中
————————————————
原文链接:https://blog.csdn.net/weixin_45453628/article/details/124234317
@Enable XXXX
@Enable XXXX用于启动类上进行开启功能
此注解封装了@Import注解,使得@Import导入的功能更加简明易懂。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
例如启动类上的@SpringBootApplication注解即含有此注解,实现了自动配置功能。
@Conditional
条件判断是否注册为bean
按照一定的条件判断,在满足给定条件后才会注册对应的bean到Spring IOC容器当中。
@Conditional本身是个父注解,派生出大量的子注解。
注解 | 描述 |
---|---|
@ConditionalOnClass | 判断环境中是否有对应的字节码文件 |
@ConditionalOnMissingBean | 判断没有对应的bean |
@ConditionalOnProperty | 判断配置文件中有对应的属性和值 |
@ConditionalOnBean | … |
@ConditonalOnCloudPlatform | … |
… | … |
Spring Cache
Spring Cache 是一个框架,实现了基于注解的缓存功能
Spring Cache提供了一层抽象,底层可以切换不同的缓存实现,例如:EHCache、Caffeine、Redis等等
@EnableCaching
开启注解缓存功能,通常加在启动类上
@Cacheable
用于查询方法上
@Cacheble注解表示这个方法有了缓存的功能,方法的返回值会被缓存下来,下一次调用该方法前,会去检查是否缓存中已经有值,如果有就直接返回,不调用方法。如果没有,就调用方法,然后把结果缓存起来。
@Cacheable(cacheNames = "setmealCache", key = "#categoryId")
public Result<List<Setmeal>> list(Long categoryId) {
Setmeal setmeal = new Setmeal();
setmeal.setCategoryId(categoryId);
setmeal.setStatus(StatusConstant.ENABLE);
List<Setmeal> list = setmealService.list(setmeal);
return Result.success(list);
}
@CachePut
用于新增方法上,将方法的返回值放到缓存当中。
@CacheEvict
用于新增或删除上,将一条或多条的数据删除。
Spring Task
Spring Task是Spring框架提供的任务调度工具,可以按照约定的时间自动执行某个代码逻辑。
@EnableScheduling
标注在启动类上,用来开启自定义定时任务类。
@Scheduled
定义在定时任务类方法上,用来设置执行时间。
@Scheduled(cron = "0 * * * * ? ")
public void processTimeoutOrder(){
}
cron属性设置为cron表达式。
aspect篇
@Aspect
用来标识这是一个实现SpringAOP的aspect类。
SpringAOP是Spring框架的高级技术,旨在管理bean对象的过程中,主要通过底层的动态代理机制,对特定的方法进行编程。
若要使用SpringAOP,要在aspect类上加上@Component, @Aspect注解。并且在方法上加通知类型。
@Around, @Before, @After, @AfterReturning, @AfterThrowing
标注在SpringAOP的aspect类的方法上。
通知类型 | 描述 |
---|---|
@Around | 环绕通知,调用proceed()方法,返回Object对象 |
@Before | 前置通知,即在方法执行前执行 |
@After | 后置通知,即在方法执行后执行 |
@AfterReturning | 返回后通知,即在方法成功执行后执行 |
@AfterThrowing | 异常后通知,即在方法抛出异常后执行 |
在每个通知类型注解内,需要指定切入点,即需要对哪个方法运用AOP,切入点表达式有两种形式,可以根据方法的签名来匹配和根据注解匹配,前者为execution(),后者为@annotation()。
@Before("execution(* com.example.mapper.*.*(..)) && @annotation(com.example.annotation.AutoFill)")
public void autoFill(JoinPoint joinPoint){
}
@PointCut
用于SpringAOP中抽取公共的切入点
将公共的切点表达式抽取出来,需要用到时引用该切点表达式即可。
@Pointcut("execution(* com.example.mapper.*.*(..)) && @annotation(com.example.annotation.AutoFill)")
public void autoFillPointCut(){}
@Before("autoFillPointCut()")
public void autoFill(JoinPoint joinPoint){
@annotation
用于SpringAOP中根据注解匹配切入点
Lombok篇
该篇所有注解均用在实体类上,用于简化我们的代码。
@Getter, @Setter
用来生成实体类的get和set方法。
@ToString
用来生成实体类的toString方法。
@EqualsAndHashCode
用来重写实体类的equals和hashCode方法
@Data
以上三个注解的总和
@NoArgsConstructor
用来生成无参构造方法
@AllArgsConstructor
用来生成全参构造方法
以上注解在平时使用中,我主要使用后三个注解,可以满足大部分需求。
Mybatis篇
该篇注解大部分均是在Java程序中对数据库操作所需要的注解。
@Insert
在内输入sql语句,执行insert语句。
@Insert("insert into user(name, age) values (#{name}, #{age})")
void insert(User user);
@Update
在内输入sql语句,执行update语句。
@Update("update user set name = #{name}, age = #{age}")
void update(User user);
@Select
在内输入sql语句,执行select语句。
@Select("select * from user where id = #{id}")
void select(User user);
@Delete
在内输入sql语句,执行delete语句。
@Delete("delete from user where id = #{id}")
void delete(User user);
@Options
用于设置对数据库进行操作之后的各个选项。
例如以下是在数据添加成功后,需要获取插入数据库的数据的主键。
@Insert("insert into user(name, age) values (#{nams}, #{age})")
@Options(keyProperty = "id", useGeneratedKeys = true)
void insert(User user);
@Results, @Result
当实体类属性名和数据库查询一致时,会自动封装。但是若不一样时,我们可以在sql语句中,对不一样的起别名,别名和属性名一致也可完成自动封装。
若我们不想采用起别名的方式,我们可以使用手动结果映射来完成封装。
例如我们想将user表的username和userage映射到User类的userName和userAge上。
@Select("select * from user where id = #{id}")
@Results({
@Result(column = "username", property = "userName")
@Result(column = "userage", property = "userAge")
})
User select(Integer id);
@Mapper
用于标识Mapper接口
在SpringBoot篇中,我们提到了@Repository注解,它被用在Dao层上,然而写jdbc代码实在太过于麻烦,因此 使用mybatis,@Mapper注解被运用于Mapper接口上。
日志篇
@Slf4j
俗称“酸辣粉4斤”,用于输出打印日志,我们常使用。
@Slf4j
public class A{
void aaa(){
log.info("我叫aaa!!")
}
}
knife4j篇
@Api
用在类上,表示对类的说明。
@ApiModel
用在实体类上,表示一个模型。
@ApiModelProperty
用在实体类的属性上,描述属性信息。
@ApiOperation
用在方法上,表示对方法的说明。
Jackson Databind篇
@JsonFormat
用于对日期格式进行转换
在属性上加入注解,对日期进行格式化。
@JsonFormat(shape =JsonFormat.Shape.STRING,pattern ="yyyy-MM-dd HH:mm:ss",timezone ="GMT+8")
private LocalDateTime createTime;
本人刚开始学习,仍为小白,若发现文章有什么错误或者是缺漏,可私信或者是评论,谢谢各位指教!