注解常识回顾
第一:分类
(1)jdk 自带的注解(5 个):罕用的就一个:@Override
(2)元注解(5 个):罕用的两个:@Target(指定注解应用的地位)@Retention(形容生命周期)
(3)自定义注解:(框架里大部分都是)
第二:元注解
@Target 指定其余注解能够应用的地位(包上、类上、办法上、属性上)@Retention 指定其余注解的生命周期(源文件中、运行时、class 文件中)@Documented 示意将该注解形容的注解外部的正文局部,也生成到相应的 API 中
第三:自定义注解
自定义注解须要配合元注解应用(罕用 @Target&@Retention)
第四:@Target 注解(指定其余注解能够应用的地位)
(1)其余注解应用在单个地位(如何指定?)@Target(ElementType.Type)(2)其余注解应用在多个地位(如何指定?)底层保护的是一个数组
@Target({ElementType.Type,ElementType.Field})(3)@Target 注解的取值{值被保护在 ElementType 中}
ElementType.Type
ElementType.Field
ElementType.Method
第五:@Retention 注解(指定其余注解的生命周期)
@Retention 注解的取值{值被保护在 RetentionPolicy 工具类中}
RetentionPolicy.SOURCE
RetentionPolicy.CLASS
RetentionPolicy.RUNTIME
第六:自定义注解论述
(1)定义:@inteface 注解名{}(2)配合元注解,指定自定义注解应用的地位,以及自定义注解的生命周期
第七:给注解增加性能 — 属性(也有人称为办法)
定义(1):
@inteface Annotation{String name(); // 没有设置默认值,应用该注解时,该属性必须增加值。//String name() default "lisi";// 给 name 赋默认值 lisi,设置了默认值后,应用该注解不须要手动设置 name 的属性值。}
应用(1):
@Annotation(name="zhangsan")
public void sayhello(){}
定义(2):
@inteface Test{int value();
//int value() default 10;// 给 value 赋默认值 10}
应用(2):
@Test(value=100)
public void sayhello(){}
因为 value 的特殊性,在应用注解时,能够省略“value=”,例如 @Test(100)
如果想间接应用 @Test 不写值 100,能够在定义注解时,设置 value 的默认值为 100
@inteface Test{int value() default 100;// 给 value 赋默认值 100
}
问题剖析:
@inteface Test{String name() default "lisi";// 给 name 赋默认值 lisi
int value() default 100;// 给 value 赋默认值 100}
(1)能够间接应用这个注解,间接写 @Test
(2)保留 name 的默认值,改 value 的值(”value=” 可省略)@Test(10)
(3)保留 value 的默认值,改 name 的值(“value=”可省略)
@Test(name="张三")
(4)同时改两个值时(”value=” 不能省略)
@Test(name="张三",value=10)
第八:框架(framework)中罕用的注解
(1)@SpringBootApplication
形容 SpringBoot 工程启动类的特定注解
(2)@SpringBootTest
形容 SpringBoot 工程测试类的特定注解
应用条件:如果须要在测试类中,引入 spring 容器机制,这是才是用该注解,否则没必要加。
引入 spring 容器机制:比如说,咱们要在测试类中,通过 spring 容器来注入某个类的实例时,就须要应用该注解。
(3)@AutoWired
主动拆卸 - 由 Spring 框架为咱们指定的属性类型注入值. 咱们罕用接口类型的变量来接管 spring 框架注入的值(多态的思维,为了升高耦合,让程序更容易保护)
具体的注入(DI)过程:
@AutoWired
Student student;属性的类型 属性名
(1)第一:(Student 为一个类)spring 框架会基于属性的类型的首字母小写(student)作为 key 去 bean 池(单例)中(多例用的时候才创立)去寻找对应的 value(这个 value 就是对象),在注入给这个属性名(注入的其实是一个地址而并非对象);
(2)第二:(Student 为接口类型)若该实现类只有一个,则间接注入;
(3)第三:若该接口的实现类有多个,此时会依据属性名 student,去查找对应的实现类创立的对象(这个对象存在 map 中的 key 为类名首字母小写),找到间接注入,找不到就间接抛异样:NoUniqueBeanDefinitionException
解决办法两种:(个别开发中都不举荐)办法 1:批改 bean 的名字(默认是类名首字母小写);@Component(“指定的名字”),这个指定的名字必须与咱们要注入的属性名一摸一样;办法 2:批改属性名(改成某个实现类的类名首字母小写);
罕用办法就是指定用哪个实现类!应用(@Qualifier 注解)
@AutoWired(required=false)在我的项目启动的第一工夫,能够不注入值(能注入则注入,不能注入则跳过)。
与 @Resource 注解拆卸过程辨别,参见 @Resource 注解(地位:第 47 个注解)
(4)@Component
不明确这个类属于哪层时能够用该注解,将该类 的实 列交给 spring 容器创立
(5)@Controller
该注解用于形容管制层,将管制层的实例创立权限 交给 spring 容器
返回的是 view
(6)@Service
该注解用于形容业务层,由 spring 来创立 @Service 形容的类的实例
(7)@Lazy
该注解用于提早对象的创立,在 springboot 我的项目中,对于 单例对象默认在我的项目启动时创立,这样会耗时耗资源 - 单例对象是要存 到 bean 池中的,通常配合 [@Scope(singleton)] 注解应用,对于 @Scope(”prototype”)形容的类的对象就是在须要时创立,按需加 载,故 @Lazy 注解对多利作用域对象不起作用
(8)@Scope
有两个取值 @Scope(”prototype”)、@Scope(”singleton”)
(9)@Test
(单元测试的注解)
满足以下条件(1)拜访修饰符不能为 private(2)返回值必须为 void(3)办法参数必须时无参(4)测试方法容许抛出异样
扩大 —- 测试的第二种办法(CommandLineRunner)
在启动类(@SpringBootApplicaton)中实现这个接口,重写 run()办法, 在 run()办法中写咱们测试代码;当启动类启动时会主动执行 run()办法
(10)@Bean
通常用于配置类中,与 @Configuration 配合应用
@Bean 形容的办法的返回值(返回的是一个对象)交给 spring 去 治理。此时能够配合 @Lazy 注解应用
(11)@Mapper
增加在数据层的接口上,告诉 spring,该接口的实现类有 mybatis 负责实现,该实现类的对象有 mybatis 创立,然而交给 spring 治理
(12)@MapperScan(“ 接口文件的包名 ”)
增加在主启动类上,利用包扫描的形式,为指定包下的接口创立代理类以及代理对象并交给 spring 治理
劣势:不必在每个映射的接口上应用 @Mapper 注解了
前提:要将所有的映射文件放在同一个包下。
(13)@Repository
增加在数据层接口的实现类上,将这个类交给 Spring 治理
(14)@Param
当 mybatis 版本绝对较低时,在动静 sql 中想要应用办法中的参数变量来获取数据,就须要应用该注解对参数变量进行形容
也与 jdk 的版本无关(往下看~~~~)
原理:mybatis 中规定,默认条件下能够进行单值传递 后端用任意的参数接管都能够。
有时候可能进行多值传递,须要将多值封装为 map 汇合进行参数的传递(sql 中通过 key 来取值)
旧版本时如果须要封装为单值,则必须增加 @Param 注解
新版本时能够主动增加 @param,前提条件是多值传递
单值:数组 collection=”array”(mapper 层传的是数组,此时数组就是一个单值,此时 xml 中的 collection=”array”)
单值:汇合 collection=”list”(mapper 层传的是 list 汇合,此时数组就是一个单值,此时 xml 中的 collection=”list”)
多值:利用 @param 注解封装 collection=”key”(mapper 层传的是 map,此时这个 map 就是一个单值,此时 xml 中的 collection=”key”)
(15)@ReponseBody
1. 形容的办法的返回值不是 view(不是一个页面),
2. 比如说能够是一个字符串 String— 间接返回该字符串
3. 当办法的返回值是一个或多个 pojo 对象(也能够是 map)时,springmvc 去查看这个办法上是否有该注解,若有,就会 pojo 对象转成 JSON 格局的字符串(字符串数组)
(16)@RestController
@Controller+@ReponseBody
个别实用于 ajax,不走视图解析器,并且返回 json 数据
(17)@PathVariable
当咱们的办法参数要从 url 中获取参数时,就须要应用该注解 –restful 格调中罕用!
如果 url 中的名字与办法参数名不统一,还能够指定
url="menu/menulist"
1.url 中的名字与办法参数名统一,能够间接加上 @PathVariable,不必指定别名
@RequestMapping("{do}/{dolist}")
public String domain(@PathVariable String dolist){return dolist;}
@RequestMapping("{do}/{dolist}")
public String domain(@PathVariable String do){return do;}
* * *
2.url 中的名字与办法参数名不统一,还能够指定,表明办法参数中的变量时来自 url 中的哪一个(个别不必这样的,间接写成一样就能够了(第一种))@RequestMapping("{do}/{dolist}")
public String domain(@PathVariable("dolist")String name){return name;}
@RequestMapping("{do}/{dolist}")
public String domain(@PathVariable("do")String name){return name;}
(18)@RequestMapping
申请映射 - 提供映射门路 - 能够应用在类上、办法上
(19)@ControllerAdvice
该注解形容类为全局异样解决类
当 Spring mvc(web)的管制层出现异常,首先会查看 controller 中是否有对应的异样解决办法,有则间接执行,若没有,就会检索是否有 @ControllerAdvice 形容的类,若有,则再去检索类中是否有对应的异样解决办法。。
(20)@ExceptionHandler
该注解形容的办法,为一个异样解决的办法,注解中须要指定能解决的异样类型(RuntimException.class- 字节码对象),示意该办法可能解决该类型的异样以及子类异样。
在异样解决办法中,通常须要一个异样参数,用来接管异样对象。
办法的返回值通常是一个对象(json 格局 - 满足响应式布局),通常与 @ReponseBody 注解联合应用
(21)@Aspect
该注解形容的类为一个切面(aop)
(22)@Around(盘绕告诉)优先级最高
执行指标办法之前 Spring 会检测是否有切面(@Aspect 形容的类),而后检测是否有告诉办法(@Around 注解形容的办法),有该办法则执行该办法,在办法中调用通过 ProceedingJoinPoint 对象 jp 调用 proceed()办法(该办法会执行指标办法)
(23)@Before
当 @Around 注解形容的办法中,要执行指标办法之前(proceed 办法执行之前),执行该注解形容的办法
(24)@After
指标办法执行之后,执行此注解形容的办法(如果指标办法有异样该办法不执行)
(25)@AfterReturnning
@After 注解形容的办法执行之后,(这个办法执行了,阐明指标办法没有抛出异样)执行该注解形容的办法。
(26)@AfterThrowing
@Around 注解形容的办法中的指标办法执行时抛出异样了,就间接执行该注解形容的办法。
(27)@Slf4j(lombok 中)
利用在类上,此类中就能够应用 log 对象
就相当于在这个类中增加了一行如下代码
Logger log=LoggerFactory.getLogger(类名.class);
(28)@PointCut
该注解用来定义切入点办法
@Pointcut("bean(sysUserServiceImpl)")
**public** **void** logPointCut() {}
切入点示意有四种:
bean execution within @annocation
(29)@Order(1)
该注解用于指定切面的优先级,数字越小,优先级越高,默认值是整数的最大值即默认值的优先级是最低的
(30)@Transactional
该注解能够形容类和办法,
当形容类时,示意类中的所有办法在执行之前开启事务,办法执行之后完结事务。
当形容办法时,示意该办法在执行之前开启事务,办法执行之后完结事务。
优先级问题:当类上和办法上都有该注解时,办法上的优先级高于类上的。
该注解中的属性也很重要:
timeout:设置超时工夫
isolation:设置隔离级别
rollbackfor:当遇到什么异样以及子类异样时要执行回滚操作。
read-only:指定事务是否为只读事务,默认值为 false;为了疏忽那些不须要事务的办法,比方读取数据,能够设置 read-only 为 true。对增加,批改,删除业务 read-only 的值应该为 false。
propagation:
Propagation.REQUIRED(如果没有事务创立新事务, 如果以后有事务参加以后事务, Spring 默认的事务流传行为是 PROPAGATION_REQUIRED,它适宜于绝大多数的状况。)
Propagation.REQUIRES_NEW
如果有以后事务, 挂起以后事务并且开启新事务
(31)@EnableAsync
注解利用到启动类上,示意开启异步,spring 容器启动时会创立线程池
spring 中线程池的配置:
spring:
task:
execution:
pool:
queue-capacity: 128
core-size: 5
max-size: 128
keep-alive: 60000
thread-name-prefix: db-service-task-
(32)@Async
在须要异步执行的业务办法上,应用 @Async 办法进行异步申明。
阐明:AsyncResult 对象能够对异步办法的执行后果进行封装,如果外界须要异步办法后果时,能够通过 Future 对象的 get 办法获取后果。
为了简便某些状况下,咱们能够将办法的返回值写成 void,这样就不要这么简单的封装(前提时办法的返回值咱们不应用)。
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Async
@Override
public Future<Integer> saveObject(SysLog entity) {
System.out.println("SysLogServiceImpl.save:"+
Thread._currentThread_().getName());
int rows=sysLogDao.insertObject(entity);
//try{Thread._sleep_(5000);}catch(Exception e) {}
return new AsyncResult<Integer>(rows);
}
(33)@EnableCaching
在我的项目 (SpringBoot 我的项目) 的启动类上增加 @EnableCaching 注解, 以启动缓存配置。
在须要进行缓存的业务办法上通过 @Cacheable 注解对办法进行相干形容. 示意办法的
返回值要存储到 Cache 中, 如果在更新操作时须要将 cache 中的数据移除, 能够在更新办法上应用 @CacheEvict 注解对办法进行形容。
@Cacheable(value = "menuCache")
@Transactional(readOnly = **true**)
**public** List<Map<String,Object>> findObjects() {....}
value 属性的值示意要应用的缓存对象, 名字本人指定,其中底层为一个 map 对象,当向 cache 中增加数据时,key 默认为办法理论参数的组合。
(34)@Value
阐明:该注解独自应用(不配合 @PropertySource 注解)时,此时配置文件曾经被加载到 spring 容器中,示意从 spring 容器(加载的配置文件)中取值。
该注解配合 @PropertySource 注解应用时,能够从指定的配置文件中取值,value 属性指定配置文件的所在门路 @PropertySource(value="classpath:/properties/image.properties",encoding="utf-8")
该注解用于形容属性的值,能够用来取出配置文件中的 value 值(依据 key 来取值)(properties、yml)、
properties 配置文件的优先级高于 yml 配置文件的优先级
当这两个文件中都用同一个属性时,优先读取 properties 配置文件中的,而后读取 yml 配置文件中的,所有最初失去的是 yml> 中的(key 雷同值被笼罩)。
@value(“${server.port}”)private String port;
阐明:
因为配置文件中的 value 值都是字符串类型,所以这里须要用 String 类型接管。该注解配合 spel 表达式取出配置文件中对应 key 的值。
(35)@PropertySource(value=”classpath:/properties/image.properties”,encoding=”utf-8″)
当配置文件曾经被加载到 spring 容器中了,就不要应用该注解指明加载的配置文件了,容器中有间接用 @Value 取值即可。
阐明:该注解用于类上,作用:读取指定地位的配置文件信息,加载该文件到 spring 容器中
value 属性用来指定配置文件的门路
classpath:/ 指定类目录下的门路(resource 目录下)
encoding:用来指定配置文件的编码类型
@PropertySource(value="classpath:/properties/image.properties",encoding="utf-8")
public class ReadProperties{}
(36)@Data(lombok)
该注解用在 pojo 类上,作用是生成对应的 get/set/toString… 办法
toString()办法只会重写本人的属性,不会增加父类的属性。
(37)@Setter(lombok)
该注解用在 pojo 类上,生成 set 办法
(38)@Getter(lombok)
该注解用在 pojo 类上,生成 get 办法
(39)@NoArgsConstructor(lombok)
该注解用在 pojo 类上,生成无参的构造方法
(40)@NoArgsConstructor(lombok)
该注解用在 pojo 类上,生成全参的构造方法
(41)@Accessors(chain=true)(lombok 提供)
提供链式加载(对于 set 办法)
User user=new User();
user.setName("张三").setAge(26).setScore(98);
(42)@TableName(“表名”)(mybatisplus 提供)
该注解用在 pojo 类上,用来指定该类的对象,与数据库中的哪张表映射
当 pojo 类名疏忽大小写时,与数据库中要映射的表名统一时,能够不指定表名。如间接写 @TableName 注解即可。但不能省略这个注解。
(43)@TableId(type=IdType.Auto)(mybatisplus 提供)
该注解用于 pojo 类中的属性上,用来指定表中的主键要映射到 pojo 类中的哪个属性。
(44)@TableField(value=” 字段名 ”)(mybatisplus 提供)
@TableField(fill = FieldFill.INSERT)指定哪个属性,在新增时无效,个别是创立工夫
@TableField(fill = FieldFill.INSERT_UPDATE)指定哪个属性,在新增和批改时无效,个别是创立工夫 / 批改工夫
该注解用于 pojo 类中的属性上,用来指定表中的字段(除主键外的其余字段)映射到 pojo 类中的哪个属性。
当字段名与属性名统一时,或者,驼峰命名后字段名与属性名统一时,能够省略这个注解 @TableField,即 pojo 中的属性上不写该注解。
(45)@GetMapping(“/page/{moduleName}”)
该注解用来解决查问申请,其余申请有效。
该注解相当于
@RequestMapping(value="/page/{moduleName}",method=RequestMethod.GET)
restful 格调:能够依据申请的形式,来执行特定的业务性能。TYPE=GET 解决查问业务
TYPE=POST 解决新增业务
TYPE=PUT 解决批改业务
TYPE=DELETE 解决删除业务
result 格调总结:1. 能够获取 url 中的参数配合 @PathVariable 注解
2. 依据申请形式,执行特定的业务性能
(46)@RestControllerAdvice
@RestControllerAdvide=@ResponseBody+@ControllerAdvide
阐明:
该注解利用于类上,示意为告诉办法。类中的办法的返回值都不是 view,返回的是 JSON 格局的数据。
该注解形容的类为全局异样解决类,解决 Controller 层呈现的异样。
(47)@Resource
@Resource 的作用相当于 @Autowired,只不过 @Autowired 按 byType 主动注入,而 @Resource 默认按 byName 主动注入罢了。@Resource 有两个属性是比拟重要的,分是 name 和 type,Spring 将 @Resource 注解的 name 属性解析为 bean 的名字,而 type 属性则解析为 bean 的类型。所以如果应用 name 属性,则应用 byName 的主动注入策略,而应用 type 属性时则应用 byType 主动注入策略。如果既不指定 name 也不指定 type 属性,这时将通过反射机制应用 byName 主动注入策略。
@Resource 拆卸程序
- 如果同时指定了 name 和 type,则从 Spring 上下文中找到惟一匹配的 bean 进行拆卸,找不到则抛出异样
- 如果指定了 name,则从上下文中查找名称(id)匹配的 bean 进行拆卸,找不到则抛出异样
- 如果指定了 type,则从上下文中找到类型匹配的惟一 bean 进行拆卸,找不到或者找到多个,都会抛出异样
- 如果既没有指定 name,又没有指定 type,则主动依照 byName 形式进行拆卸;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则主动拆卸;
(48)@ComponentScan(basePackages={“ 包的门路 ”})
扫描指定门路下的类,看是否有类上 @Component、@Controller、@Service、@Mapper 等,若有则指明该类的实例由 Spring 容器创立。
(49)@RequestBody
1、@requestBody 注解罕用来解决 content-type 不是默认的 application/x-www-form-urlcoded 编码的内容,比如说:application/json 或者是 application/xml 等。个别状况下来说罕用其来解决 application/json 类型。
2、通过 @requestBody 能够将申请体中的 JSON 字符串绑定到相应的 bean 上,当然,也能够将其别离绑定到对应的字符串上。
@RequestBody 和 @RequestParam 区别
@RequestParam
注解 @RequestParam 接管的参数是来自 HTTP 申请体或申请 url 的 QueryString 中。
RequestParam 能够承受简略类型的属性,也能够承受对象类型。
@RequestParam 有三个配置参数:
required 示意是否必须,默认为 true,必须。defaultValue 可设置申请参数的默认值。value 为接管 url 的参数名(相当于 key 值)。
@RequestParam
用来解决 Content-Type 为 application/x-www-form-urlencoded 编码的内容,Content-Type 默认为该属性,也能够接管application/json。@RequestParam 也可用于其它类型的申请,例如:POST、DELETE 等申请. 所以在 postman 中,要抉择 body 的类型为 x-www-form-urlencoded,这样在 headers 中就主动变为了 Content-Type : application/x-www-form-urlencoded 编码格局。@RequestBody
注解 @RequestBody 接管的参数是来自 requestBody 中,即申请体。个别用于解决非 Content-Type: application/x-www-form-urlencoded 编码格局的数据,比方:application/json、application/xml 等类型的数据。就 application/json 类型的数据而言,应用注解 @RequestBody 能够将 body 外面所有的 json 数据传到后端,后端再进行解析。GET 申请中,因为没有 HttpEntity,所以 @RequestBody 并不实用。
POST 申请中,通过 HttpEntity 传递的参数,必须要在申请头中申明数据的类型 Content-Type,SpringMVC 通过应用
HandlerAdapter 配置的 HttpMessageConverters 来解析 HttpEntity 中的数据,而后绑定到相应的 bean 上。因为 @RequestBody 可用来解决 Content-Type 为 application/json 编码的内容,所以在 postman 中,抉择 body 的类型为 rowJSON(application/json),这样在 Headers 中也会主动变为 Content-Type : application/json 编码格局。
(50)@JsonFormat
在你须要查问进去的工夫的数据库字段对应的实体类的属性上增加 @JsonFormat
能够很好的解决:后盾到前台工夫格局保持一致的问题
(51)@DateTimeFormat
在你须要查问进去的工夫的数据库字段对应的实体类的属性上增加 @DataTimeFormat
能够很好的解决: 前台到后盾工夫格局保持一致的问题
@DateTimeFormat(pattern ="yyyy-MM-dd")
@JsonFormat(pattern ="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private Date symstarttime;