Spring各种注解的含义及用法(持续更新)

2021-06-05 09:02

阅读:596

,作用为:配置spring容器(应用上下文) @Configuration注解的spring容器加载方式,用AnnotationConfigApplicationContext替换ClassPathXmlApplicationContext

ApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class);

如果加载spring-context.xml文件:
ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");

@Param

标记在dao层方法中的普通参数前,可以在xml中不需要使用 parameterType 进行声明可以直接使用,标记在实体类参数前,需要在xml中使用 别名.属性 的方式使用实体类的变量,建议实体类参数不加,不加可以在xml中直接使用 变量名。 在使用List作为查询条件时,需要设置 @Param 否则会报错 接口方法示例:
List getTimeLineColumn(@Param("cbIds") List cbIds)throws Exception;

xml中示例:

2.SpringBoot中常见注解

@RestController

@RestController注解相当于@ResponseBody + @Controller合在一起的作用。 1) 如果只是使用@RestController注解Controller,则Controller中的方法无法返回jsp页面,或者html,配置的视图解析器 InternalResourceViewResolver不起作用,返回的内容就是Return 里的内容。 2) 如果需要返回到指定页面,则需要用 @Controller配合视图解析器InternalResourceViewResolver才行。 如果需要返回JSON,XML或自定义mediaType内容到页面,则需要在对应的方法上加上@ResponseBody注解。

@SpringBootApplication

用于标注启动类上,相当于@EnableAutoConfiguration(自动注入相关配置类)、@ComponentScan和@Configuration的合集。

@ImportResource

用来加载xml配置文件

@PathVaribale

获取restful请求中的数据
@RestController
public class HelloController {
 
  @RequestMapping(value="/hello/{id}",method= RequestMethod.GET)
  public String sayHello(@PathVariable("id") Integer id){
    return "id:"+id;
  }
}

@RequestParam

获取请求参数的值 localhost:8080/hello?id=1000
@RestController
public class HelloController {
 
  @RequestMapping(value="/hello",method= RequestMethod.GET)
  public String sayHello(@RequestParam("id") Integer id){
    return "id:"+id;
  }
}

@RequestBody

注解可以接收json格式的数据,并将其转换成对应的数据类型
当前台界面使用GET或POST方式提交数据时,数据编码格式由请求头的ContentType指定。分为以下几种情况:
1. application/x-www-form-urlencoded,这种情况的数据@RequestParam、@ModelAttribute可以处理,@RequestBody也可以处理。
2. multipart/form-data,@RequestBody不能处理这种格式的数据。(form表单里面有文件上传时,必须要指定enctype属性值为multipart/form-data,意思是以二进制流的形式传输文件。)
3. application/json、application/xml等格式的数据,必须使用@RequestBody来处理。
用于post请求,不能用于get请求

@RequestParam 和 @RequestBody 一起使用在接口上时

@PostMapping(value = ConstScheduleUrl.COMMON_ADDACCESSORYLIST)
public ResponseResult addAccessoryList(@RequestParam("workPlanId") String workPlanId,@RequestBody ScheduleCommonWorkPlanVO commonWorkPlanVO){
    commonWorkPlanCodeService.commonHandleAccessory(commonWorkPlanVO,workPlanId);
    return ResponseResult.success();
}

@EnableScheduling

加在SpringBoot的启动类上开启对定时任务的支持,配合@Scheduled使用

@Scheduled

Scheduled注解中有以下几个参数:
cron
zone
fixedDelay和fixedDelayString
fixedRate和fixedRateString
initialDelay和initialDelayString
1.cron是设置定时执行的表达式,如 0 0/5 * * * ?每隔五分钟执行一次
2.zone表示执行时间的时区
3.fixedDelay 和fixedDelayString 表示一个固定延迟时间执行,上个任务完成后,延迟多长时间执行
4.fixedRate 和fixedRateString表示一个固定频率执行,上个任务开始后,多长时间后开始执行
5.initialDelay 和initialDelayString表示一个初始延迟时间,第一次被调用前延迟的时间

@EnableCaching

开启缓存,配合@Cacheable使用 value:缓存位置名称,不能为空,如果使用EHCache,就是ehcache.xml中声明的cache的name key:缓存的key,默认为空,既表示使用方法的参数类型及参数值作为key,支持SpEL condition:触发条件,只有满足条件的情况才会加入缓存,默认为空,既表示全部都加入缓存,支持SpEL
//将缓存保存进andCache,并使用参数中的userId加上一个字符串(这里使用方法名称)作为缓存的key     
@Cacheable(value="andCache",key="#userId + ‘findById‘")    
public SystemUser findById(String userId) {    
    SystemUser user = (SystemUser) dao.findById(SystemUser.class, userId);          
    return user ;           
}

//将缓存保存进andCache,并当参数userId的长度小于32时才保存进缓存,默认使用参数值及类型作为缓存的key    
@Cacheable(value="andCache",condition="#userId.length 

@CacheConfig

含义:指定要用于该类的每个高速缓存操作的高速缓存的名称可以由单个类级定义代替。即该方式属于类级别操作。 示例:
//定义该类中的所有缓存在CACHE_SYS_PAPER 里
@Service
@CacheConfig(cacheNames = { CacheConstants.CACHE_SYS_PAPER })
public class ScheduleTrainPaperService {
    ...
}

@Cacheable

含义:当调用该注解声明的方法时,会先从缓存中查找,判断是否有key相同缓存的数据,如果有,就直接返回数据,如果没有,执行方法,然后把返回的数据以键值的方式存储到缓存中,方便下次同样参数请求时,直接从缓存中返回数据。
@Cacheable支持如下几个参数:
cacheNames:缓存位置的一段名称,不能为空,和value一个含义。
value:缓存位置的一段名称,不能为空,和cacheNames一个含义。
key:缓存的key,默认为空,表示使用方法的参数类型及参数值作为key,支持SpEL。
keyGenerator:指定key的生成策略。
sync: 默认false,设置为true 表示并发访问时,多个线程只有1个线程可以访问数据库,其他线程都会等待直到缓存可用
condition:触发条件,满足条件就加入缓存,默认为空,表示全部都加入缓存,支持SpEL。
//SpEL方式定义key
CacheConstants.CACHE_ROOT_METHOD_NAME_ID="#root.methodName + #id"

@Cacheable(key = CacheConstants.CACHE_ROOT_METHOD_NAME_ID ,sync =true)
public ScheduleTrainOption get(Integer id) {
   return trainOptionMapper.get(id);
}

@CacheEvict

含义:当存在相同key的缓存时,把缓存清空,相当于删除。
cacheNames:缓存位置的一段名称,不能为空,和value一个含义。
value:缓存位置名称,不能为空,和cacheNames一个含义
key:缓存的key,默认为空,表示使用方法的参数类型及参数值作为key,支持SpEL
condition:触发条件,只有满足条件的情况才会清除缓存,默认为空,支持SpEL
allEntries:true表示清除value中的全部缓存,默认为false

@CahePut

@CachePut也可以声明一个方法支持缓存功能。与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中

@EnableTransactionManagement

开启事务支持,然后在访问数据库的Service方法上添加注解 @Transactional 便可 关于事务管理器,不管是JPA还是JDBC等都实现自接口 PlatformTransactionManager 如果你添加的是 spring-boot-starter-jdbc 依赖,框架会默认注入 DataSourceTransactionManager 实例。如果你添加的是 spring-boot-starter-data-jpa 依赖,框架会默认注入 JpaTransactionManager 实例

@MapperScan

通过使用@MapperScan可以指定要扫描的Mapper类的包的路径
@SpringBootApplication
@MapperScan("com.lz.water.monitor.mapper")

//也可以同时扫描多个包
@SpringBootApplication  
@MapperScan({"com.kfit.demo","com.kfit.user"})  

//如果mapper类没有在Spring Boot主程序可以扫描的包或者子包下面,可以使用如下方式进行配置
@SpringBootApplication  
@MapperScan({"com.kfit.*.mapper","org.kfit.*.mapper"})  

@ConfigurationProperties

注解支持两种方式
加在类上,需要和@Component注解,结合使用.代码如下:
@Component
@ConfigurationProperties(prefix = "com.example.demo")

通过@Bean的方式进行声明,这里我们加在启动类即可,代码如下

@Bean
@ConfigurationProperties(prefix = "com.example.demo")

prefix 全部要改成小写,不可以配合@value 使用会报错

java.lang.IllegalArgumentException: Could not resolve placeholder ‘defaultPoints‘ in value "${defaultPoints}"

@ProtertySource

.yml 格式不支持 @PropertySource 注解导入配置 用法1- @PropertySource和@Value
@PropertySource("classpath:jdbc.properties")
@Value(${jdbc.driver})
private String driver;

也可以配合@ConfigurationProperties 使用

@ExceptionHandler

统一处理某一类异常,从而能够减少代码重复率和复杂度

@ControllerAdvice

异常集中处理,更好的使业务逻辑与异常处理剥离开 抛出Exception异常就可以被捕获到,也可以在@ExceptionHandler(定义自己的异常类)

@RestControllerAdvice

在spring 3.2中,新增了@ControllerAdvice,@RestControllerAdvice 注解,可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,
并应用到所有@RequestMapping中
主要配合@ExceptionHandler使用,统一处理异常情况。下面的ResponseEntity、ResponseData 都是项目自定义的返回对象
controller层统一处理异常,service及其他被调用代码块只负责抛出异常即可,
service层不显式抛出自定义异常的话,可以通过自定义全局异常处理类可以统一抛出某个自定义提示
例如如下代码:
定义全局异常处理类
@RestControllerAdvice
public class RmcpExceptionHandler {
    private final static Logger logger = LoggerFactory.getLogger(RmcpExceptionHandler.class);

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResponseResult handle(Exception e) {
        ResponseResult result = new ResponseResult();
        if (e instanceof RmcpException) {
            // 系统自定义异常
            ....
        } else if (e instanceof ConstraintViolationException) {
            ....
        } else if (e instanceof MethodArgumentTypeMismatchException) {
           ...
        } else if (e instanceof MethodArgumentNotValidException){
            ...
        }
        else if (e instanceof HttpMessageNotReadableException) {
            ...
        } else {
            // 未知异常
            ...
        }

        e.printStackTrace();
        return result;
    }
}

@ResponseStatus

可以将某种异常映射为HTTP状态码

@ConditionalOnMissingBean

该注解表示,如果存在它修饰的类的bean,则不需要再创建这个bean; 可以给该注解传入参数例如@ConditionOnMissingBean(name = "example"), 这个表示如果name为“example”的bean存在,这该注解修饰的代码块不执行
@Bean
    @ConditionalOnMissingBean(name = "imageValidateCodeGenerator")
    public ValidateCodeGenerator imageValidateCodeGenerator() {
        ImageCodeGenerator codeGenerator = new ImageCodeGenerator();
        codeGenerator.setSecurityProperty(securityProperties);
        return codeGenerator;
    }

测试发现, @ConditionOnMissingBean 只能在@Bean 注释的方法上使用,不能再@Component 注释的类上使用

@PostConstruct

被@PostConstruct修饰的方法会在服务器加载Servle的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。

@PreDestroy

PreDestroy()方法在destroy()方法执行执行之后执行,如下: 我现在要说的是用实例说明它有什么作用。 比如说我有一种情况,在我的servlet初始化加载之前我想处理一些东西,像加载缓存等等。 怎么做。@PostConstruct就派上用场了。那为什么这玩意用的不多呢,这是因为如果初始化之前我们要加载或处理某些玩意完全可以在构造器初始化时就处理了,但这种方法需要自己重写构造器

@Transactional

常用传参:
1.propagation=事务传播行为
1. TransactionDefinition.PROPAGATION_REQUIRED:
如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。
2. TransactionDefinition.PROPAGATION_REQUIRES_NEW:
创建一个新的事务,如果当前存在事务,则把当前事务挂起。 内部的事务独立运行,在各自的作用域中,可以独立的回滚或者提交; 而外部的事务将不受内部事务的回滚状态影响 3. TransactionDefinition.PROPAGATION_SUPPORTS:
如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。 4. TransactionDefinition.PROPAGATION_NOT_SUPPORTED:
以非事务方式运行,如果当前存在事务,则把当前事务挂起。 5. TransactionDefinition.PROPAGATION_NEVER:
以非事务方式运行,如果当前存在事务,则抛出异常。 6. TransactionDefinition.PROPAGATION_MANDATORY:
如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。 7. TransactionDefinition.PROPAGATION_NESTED:
如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行; 如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。

PROPAGATION_REQUIRES_NEW和PROPAGATION_NESTED的区别

REQUIRES_NEW:启动一个新的,不依赖环境的“内部”事务,这个事务将被完全commited或rolled back 而不依赖于外部事务,它拥有自己的隔离范围,自己的锁等等,当内部事务开始执行时,外部事务将被挂起,内部事务结束时,外部事务将继续执行。

NESTED:如果外部事务commit,嵌套事务也会被commit;如果外部事务roll back,嵌套事务也会被 roll back。

开始一个嵌套的事务,它是已经存在事务的一个真正的子事务,嵌套事务开始执行时,它将取得一个savepoint,如果这个嵌套事务失败,我们将回滚到此savepoint,嵌套事务是外部事务的一部分,只有外部事务结束后它才会被提交


评论


亲,登录后才可以留言!