注解知识回顾
第一:分类
(1)jdk自带的注解(5个):常用的就一个:@Override
(2)元注解(5个):常用的两个:@Target(指定注解使用的位置) @Retention(描述生命周期)
(3)自定义注解:(框架里都是)
第二:元注解
@Target 指定其他注解可以使用的位置(包上、类上、方法上、属性上)
@Retention 指定其他注解的生命周期(源文件中、运行时、class文件中)
第三:自定义注解
自定义注解需要配合元注解使用(常用@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
}
使用(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)@SpringBootApplicaton 描述SpringBoot工程启动类的特定注解
(2)@SpringBootTest 描述SpringBoot工程测试类的特定注解
(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 注解)
(4)@Component(不明确这个类属于哪层时可以用该注解,将该类 的实 列交给spring容器创建)
(5)@Controller(该注解用于描述控制层,将控制层的实例创建权限 交给spring容器)
(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)@param 当mybatis版本相对较低时,在动态sql中想要使用参 数变量来获取数据,就需要使用该注解对参数变量进行描述
(13)@ReponseBody描述的方法的返回值不是view(不是一个页面),(比如说可以是一个字符串String)
(14)@RestController(@Controller+@ReponseBody)
(15)@PathVariable(当我们的方法参数要从url中获取参数时,就需 要使用该注解--restful风格中常用!)
(16)@RequestMapping(请求映射-提供映射路径-可以使用在类上、 方法上)