Annotation Points
Annotation Points
注解相关
属性注入注解
Autowired
特点:基于实体类型进行属性注入
局限:若有相同实体类型,则无法正常完成属性注入
Qualifier
特点:结合Autowired注解解决了相同实体类型无法注入的问题
Resource
特点:源自JDK原生注解,实现了Autowired + Qualifier注解的功能
常量注入
Value
作用于实体类中的属性,扫描resource下的yml/yaml文件,利用
${””}
EL表达式获取该EL键对应的值局限:必须写全key的键名
1
2
3Object:
User: user1
code: code1当注入user属性时,需要@Value(”${Object.user}”)进行注入
ConfigurationProperties (prefix=”前缀”)
作用于实体类,自动按照配置文件的前缀下的key值进行匹配并赋值
注意:必须实现相应属性的set方法!否则五福正常的属性注入!
IOC实体对象注解
Component
作用于实体类,基本的Bean注解
Controller
作用于实体类,标识为控制层Bean对象
Service
作用于实体类,表示为服务层对象
Repository
作用于实体类,标识为持久层对象
Bean
作用于方法函数,标识Bean对象并且可以给该对象起别名
如果方法需要使用到IOC容器中的Bean对象,只需要在方法中的参数列表里直接声明即可,方法会自动配置Bean对象映射到该实体上
ConponentScan注解
- Spring内的注解,让Spring扫描指定目录下的Bean文件或对象类,并自动放到IOC容器中进行管理,若不设置扫描路径,则默认为扫描当前类所在目录及其子目录下的Bean
Configuration
- 注明该类为配置类,在该注解的配置上有Conponent的注解,因此该配置类也为IOC容器管理的Bean对象
- 其作业为通过加载类的方式替代了applicationContext.xml文件的书写
lombok 注解依赖
作用:在实体类上添加该注解,会在编译阶段自动生成getter和setter方法
步骤:
- 引入依赖
1
2
3
4<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>- 添加注解@Data
对lombok依赖其他常用注解:
- AllArgsConstructor:带有全部参数的构造器
- NoArgsConstructor:空构造器
第三方Bean对象注入
Bean
- 将需要返回的对象写入通过函数返回,函数体上添加Bean注解
- 为了更好的实现代码的封装效果,一般通过实现配置类,在配置类内部实现Bean注解函数,来完成Bean的注册
Import
基本使用方法
基于配置类给于Bean对象的方法,将配置类的Class表示给Import注解,此时,该配置类可以不在boot启动程序的目录下(即可以是工程下的任意目录下)
1
2
3
4
5
6
7
8
9
10
11
12@SpringBootApplication
@Import(DemoConfigure.class)
public class DemoApplication {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(DemoApplication.class, args);
System.out.println("hello run");
System.out.println(((Testdomain)context.getBean("domain")).getUser());
}
}1
2
3
4
5
6
7
8
9@Configuration
public class DemoConfigure {
@Bean("domain")
public Testdomain testConfig(){
Testdomain testdomain = new Testdomain();
testdomain.setUser("cq");
return testdomain;
}
}结合实现ImportSelector接口
当项目复杂时,将配置类的class写入Import可能使得代码过于冗杂,因此可以借助实现ImportSelector接口的方式来注入配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52package config;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
/**
* \* Created with IntelliJ IDEA.
* \* User: ych.
* \* Date: 2024/4/25
* \* Time: 18:49
* \* Description:
* \
*/
public class DemoImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
List<String> list = new ArrayList<>();
InputStream is = DemoImportSelector.class.getClassLoader().getResourceAsStream("demoImport.imports");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
try{
while ((line = br.readLine()) != null)
list.add(line);
}catch (IOException e){
e.printStackTrace();
}finally {
// String strs[]
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(list.toArray()[0]);
return list.toArray(new String[0]);
}
}
@Override
public Predicate<String> getExclusionFilter() {
return ImportSelector.super.getExclusionFilter();
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23package com.example.demo;
import com.example.demo.domains.Testdomain;
import config.DemoConfigure;
import config.DemoImportSelector;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Import;
@SpringBootApplication
@Import(DemoImportSelector.class)
public class DemoApplication {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(DemoApplication.class, args);
System.out.println("hello run");
System.out.println(((Testdomain)context.getBean("domain")).getUser());
}
}
### 自定义组合注解
元注解
在Java中,元注解是指那些用于注释其他注解的注解。它们是Java注解机制的一部分,定义了注解如何被系统处理。Java提供了几个内置的元注解,它们都位于
java.lang.annotation
包中。以下是Java中的元注解列表及其用途:@Target: 指定了注解可以应用的Java元素类型(例如,类、方法、字段等)。它接受一个
ElementType
枚举的数组作为其值。例如:
1
2
3@Target(ElementType.METHOD)
public @interface MyAnnotation {}这意味着
MyAnnotation
只能用于方法。@Retention: 指定注解在什么级别可用,即它们的保留策略。它接受一个
RetentionPolicy
枚举的值,可能是SOURCE
(只在源代码中保留,编译器不保留),CLASS
(编译器将注解存储于类文件中,但在运行时不由虚拟机保留),或者RUNTIME
(由虚拟机在运行时保留,因此可以通过反射读取)。例如:
1
2
3@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {}这意味着
MyAnnotation
在运行时是可见的。@Documented: 指示将注解包含在JavaDoc工具处理的文档中。如果一个注解声明了
Documented
元注解,它的使用将被JavaDoc或类似的工具记录。例如:
1
2
3@Documented
public @interface MyAnnotation {}使用
MyAnnotation
的元素的文档会包含这个注解的信息。@Inherited: 指示一个注解类型会被从超类继承。默认情况下,注解不会被子类继承。如果一个注解被标记为
Inherited
,则一个使用了该注解的类的子类也将隐式地被此注解标记。例如:
1
2
3@Inherited
public @interface MyAnnotation {}如果一个类使用了
MyAnnotation
,那么其所有子类也将隐式地被MyAnnotation
注解。@Repeatable: 用于标示某个注解可以在同一个声明上多次使用。在引入
@Repeatable
之前,一个注解只能在同一个声明上使用一次。例如:
1
2
3
4
5
6
7@Repeatable(MyAnnotations.class)
public @interface MyAnnotation {}
public @interface MyAnnotations {
MyAnnotation[] value();
}这允许在同一声明上多次使用
MyAnnotation
注解。
这些元注解为Java注解提供了规则和结构,使得开发者可以创建更复杂的注解类型,以及更丰富的注解处理工具。
组合注解
自行搭配注解并构造成新的注解,在构造组合注解时一般需要搭配元注解中的Target和Retention注解,否则一般为默认值
1
2
3
4
5
6@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import(DemoImportSelector.class)
public @interface DemoDfineAnno {
}
属性/参数列表 注入
Value:在一般情况下,无论是属性注入或是参数列表注入,可以使用value注解进行注入,但若想实现复杂功能,例如参数列表的实体值未未声明时想要完成函数逻辑,则此时会编译错误,需要用到其他更复杂的注解进行处理
Conditional注解族
注解 说明 ConditionalOnProperty 配置文件中存在对应的属性,才声明该Bean ConditionalOnMissingBean 当IOC中不存在指定的Bean时,才声明该Bean ConditionalOnClass 当环境中存在指定的类时,才声明该Bean 1
2
3
4
5
6
7@ConditionalOnProperty(prefix = "spring",name = {"mybatis"})
@Bean("domain")
public Testdomain testConfig(){
Testdomain testdomain = new Testdomain();
testdomain.setUser("cq");
return testdomain;
}该测试代码逻辑为,若配置文件中存在spring的配置文件,且该spring含有mybatis配置键值,则声明该变量,否则不声明该变量(即不调用该方法)
RequestHeader注解
- 通过该注解,直接在controller的方法里指明相应的参数为请求头的哪个参数的映射
JsonIgnore
- 当该注解属性所在的对象返回时,不将该属性放入JSON串内
- 常用于隐私保护(密码等)
RequestBody
- 作用:将请求的JSON串自动封装为实体类对象并影射到方法的参数中
1 |
|
- 注意:
- 若使用该注解则前端返回时必须为JSON形式/格式的数据
- 此时若不添加该注解,直接通过名称的映射是无法获取参数的
JsonFormat
在实体类中格式化日期形式
步骤:在实体类的相应属性上添加该注解,并设置日期的格式化输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Data
public class Category {
private Integer id;//主键ID
@NotEmpty
private String categoryName;//分类名称
@NotEmpty
private String categoryAlias;//分类别名
@NotEmpty
private Integer createUser;//创建人ID
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;//创建时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;//更新时间
}
RequestParam
在JavaWeb中,@RequestParam
注解是Spring框架中用于处理HTTP请求参数的注解,主要用于从请求中获取指定名称的参数值,并将其映射到方法的参数上。下面是关于@RequestParam
注解的详细描述:
- 作用:
@RequestParam
注解用于将请求参数的值绑定到方法的参数上,可以用于处理HTTP GET、POST等请求中的参数。
- 使用场景:
- 在Spring
MVC中,处理请求时经常需要获取请求中的参数值,
@RequestParam
提供了一种方便的方式来获取这些参数。
- 在Spring
MVC中,处理请求时经常需要获取请求中的参数值,
- 常用属性:
value
:指定要绑定的请求参数的名称。例如,@RequestParam(value = "username") String username
表示将请求参数中名为username
的值绑定到username
变量上。required
:指定该参数是否是必需的,默认为true
。如果设置为true
,而请求中缺少该参数,则将抛出异常。defaultValue
:指定当请求中缺少该参数时的默认值。例如,@RequestParam(value = "page", defaultValue = "1") int pageNum
表示如果请求中没有名为page
的参数,pageNum
默认为1
。
- 示例:
下面是一个简单的示例,演示了如何在Spring MVC中使用
@RequestParam
注解:1
2
3
4
5
6@GetMapping("/hello")
public String hello(@RequestParam(value = "name", defaultValue = "Guest") String name,
@RequestParam(value = "age", required = false) Integer age) {
return "Hello " + name + "! You are " + (age != null ? age : "ageless");
}- 在上面的例子中,
hello
方法处理了一个GET请求,通过@RequestParam
注解获取了名为name
和age
的参数值。name
参数是必需的,默认值为"Guest"
,而age
参数是可选的。
- 在上面的例子中,
- 注意事项:
- 如果请求参数的名称与方法参数的名称相同,可以省略
value
属性,直接使用@RequestParam
注解,如@RequestParam String username
。 - 如果请求参数是一个数组或者集合,可以使用
List
或Array
作为方法参数类型,Spring会自动将多个同名参数值绑定到这个集合或数组中。
- 如果请求参数的名称与方法参数的名称相同,可以省略
总之,@RequestParam
注解是Spring
MVC中处理HTTP请求参数的重要注解,它提供了一种简单而灵活的方式来获取请求参数,并将其传递给Controller中的方法。
SpringBootTest
在test类上添加该注解后,在该类上使用test注解时会先启动IOC容器加载Bean对象,便于在Spring IOC容器环境下测试相应的接口和方法