Spring注解-(一)@Value的多种用法详解

本文最后更新于:June 12, 2022 am

Spring 是目前主流的 Java Web 开发框架,是 Java 世界最为成功的框架。Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。该框架是一个轻量级的开源框架,具有很高的凝聚力和吸引力。Spring 框架不局限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何 Java 应用都可以从 Spring 中受益。Spring 框架还是一个超级粘合平台,除了自己提供功能外,还提供粘合其他技术和框架的能力。

目录

配置

application.properties

1
tothefor=sssssss

TestConfig.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.SpringTestAnnotation;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;

/**
* @Author DragonOne
* @Date 2022/6/10 11:16
* @墨水记忆 www.tothefor.com
*/
@ComponentScan("com.SpringTestAnnotation")
@PropertySource("classpath:application.properties") //指明配置文件
public class TestConfig {

}

TestAnnotation.java(结果均是运行此代码得出)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.SpringTestAnnotation;

import com.SpringTestAnnotation.TestValue.Per;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
* @Author DragonOne
* @Date 2022/6/10 11:16
* @墨水记忆 www.tothefor.com
*/
public class TestAnnotation {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(TestConfig.class);
Per per = applicationContext.getBean("per", Per.class);
per.show();
}
}

正常读取(占位符)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.SpringTestAnnotation.TestValue;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
* @Author DragonOne
* @Date 2022/6/10 11:16
* @墨水记忆 www.tothefor.com
*/
@Component("per")
public class Per {

@Value("${tothefor}")
private String name;

public void show(){
System.out.println("Per show "+name);
}

}

输出

1
Per show sssssss

直接赋值(普通字符串)

直接将注解内的内容进行赋值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.SpringTestAnnotation.TestValue;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
* @Author DragonOne
* @Date 2022/6/10 11:16
* @墨水记忆 www.tothefor.com
*/
@Component("per")
public class Per {

@Value("墨水记忆")
private String name;

public void show(){
System.out.println("Per show "+name);
}

}

输出:

1
Per show 墨水记忆

还要一种情况,即在application.properties文件没有对应的Key。则也会直接输出字符串:

1
Per show ${tothefor}

使用#获取Bean

用井号(#)可以完成一个Bean的注入。

添加Bean对象类:

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.SpringTestAnnotation.TestValue;

import org.springframework.stereotype.Component;

/**
* @Author DragonOne
* @Date 2022/6/10 21:56
* @墨水记忆 www.tothefor.com
*/
@Component("orderS")
public class OrderS {
}

再用井号(#)注入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.SpringTestAnnotation.TestValue;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
* @Author DragonOne
* @Date 2022/6/10 11:16
* @墨水记忆 www.tothefor.com
*/
@Component("per")
public class Per {

@Value("#{orderS}") //注意和前面的区别
private OrderS name;

public void show(){
System.out.println("Per show "+name);
}

}

输出结果:

1
Per show com.SpringTestAnnotation.TestValue.OrderS@f4168b8

为什么会实现Bean的注入呢?

  • 因为在Value里面写的这个井号(#)表示一种Spring表达式。通过名称找到Bean,然后再将其赋值给所在的属性。如果属性和Bean类所对应类型不匹配的话,则会出现异常问题。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.SpringTestAnnotation.TestValue;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
* @Author DragonOne
* @Date 2022/6/10 11:16
* @墨水记忆 www.tothefor.com
*/
@Component("per")
public class Per {

@Value("#{orderS}")
private String name; //类型区别

public void show(){
System.out.println("Per show "+name);
}

}

自定义注解使用

当某一个配置在多个文件中均使用到时,如果再使用以下这种方法进行读取,那么一旦进行修改时就会修改大量使用到的地方的代码。

1
2
3
4
5
6
7
//A.class
@Value("${tothefor}") //配置文件中的Key
private String name;

//B.class
@Value("${tothefor}") //配置文件中的Key
private String name;

当配置文件中的Key:tothefor发生改变时,那么我们需要去A.class和B.class文件中去修改这两个地方。当有更多文件时,则更加的麻烦。可以通过注解的形式将获取值的方式进行再一次的封装。这样只需要在注解处修改Key值即可,而使用该注解的地方就不需要改动,从而实现动一发牵动全局。自定义封装注解实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.SpringTestAnnotation.TestValue;

import org.springframework.beans.factory.annotation.Value;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* @Author DragonOne
* @Date 2022/6/12 08:08
* @墨水记忆 www.tothefor.com
*/

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Value("${tothefor}")
public @interface OurAnno {
}

其中:

1
2
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)

可以参考注解@Value中直接Copy。

这样完成了注解的封装之后,我们就可以直接在需要使用该值的地方使用自定义注解即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.SpringTestAnnotation.TestValue;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
* @Author DragonOne
* @Date 2022/6/10 11:16
* @墨水记忆 www.tothefor.com
*/
@Component("per")
public class Per {

@OurAnno
private String name;

public void show(){
System.out.println("Per show "+name);
}
}

这样同样可以实现从配置文件中读取数据并进行赋值。即通过使用自定义注解@OurAnno代替了@Value(“${tothefor}”)。