英文:
@Value("${model.version:2}") is not taking up the default value = 2
问题
我有一个Spring应用程序,在其中我已经放置了以下代码,并且我正在传递mvn参数来更新值。问题是,每次我传递值时,不管值是什么,它都默认为0。您能帮助我解决这个问题吗?
这是我的小代码片段:
@Value("${model.version:2}")
private int model;
public TestClass(){
if(model == 2){
// 一些逻辑
}
}
使用mvn参数 -Dmodel.version=2
。
英文:
I have a spring application in which I have put the code as below and I'm passing mvn parameter to update the value. The problem is every time I pass the value, regardless of the value it takes 0 by default. Can you please help me solve the issue.
Here is my little code snippet
@Value("${model.version:2}")
private int model;
public test class(){
if(model == 2){
<some logic>
}
}
using mvn parameter as -Dmodel.version=2
答案1
得分: 2
简而言之:你没有使用 Spring 管理的上下文。
让我们一起走一遍这个过程。
假设有一个类 MyCoolClass
,类似于:
@Component
public class MyCoolClass {
@Value("${some.value:3}")
private int a;
public void show() {
log.info("a is " + a);
}
}
如果你进行自动装配(autowire)并调用 show()
方法,日志将会记录:
a is 3
现在让我们创建一个测试来验证它是否真的有效:
@SpringBootTest
public class MyTest {
@Autowired
private MyCoolClass myCoolClass;
@Test
public void lookAtMe() {
myCoolClass.show();
}
}
这一开始会抛出 NPE,因为 this.myCoolClass
是空的;这是某些东西不正常工作的第一个提示。让我们克服这个问题,并在我们自己的代码中实例化 myCoolClass
:
this.myCoolClass = new MyCoolClass();
this.myCoolClass.show();
a is 0
关键在于,如果你自己创建了一个 MyCoolClass 实例,那么就没有人会解析 @Value
注解并处理其中的表达式。它只是一个普通的 POJO。
要解决这个问题,你需要在类上添加 @RunWith(SpringJUnit4ClassRunner.class)
,这样一来,日志就会运行整个 Spring 应用程序启动过程,并记录 a is 3
!(当然不会调用用户创建的构造函数):
@SpringBootTest
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
public class MyTest {
@Autowired
private MyCoolClass myCoolClass;
@Test
public void lookAtMe() {
myCoolClass.show();
}
}
这就是日志的样子:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.13.RELEASE)
12:41:59 INFO 912 --- [ main] com.example.demo.MyTest : Starting MyTest on clijsters-computer with PID 912 (started by dclijsters in C:\demo)
12:41:59 INFO 912 --- [ main] com.example.demo.MyTest : No active profile set, falling back to default profiles: default
12:42:01 INFO 912 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
12:42:02 INFO 912 --- [ main] o.s.s.c.ThreadPoolTaskScheduler : Initializing ExecutorService 'taskScheduler'
12:42:02 INFO 912 --- [ main] com.example.demo.MyTest : Started MyTest in 2.513 seconds (JVM running for 3.376)
12:42:02 INFO 912 --- [ main] com.example.demo.MyTest : a is 3
12:42:02 INFO 912 --- [ Thread-3] o.s.s.c.ThreadPoolTaskScheduler : Shutting down ExecutorService 'taskScheduler'
12:42:02 INFO 912 --- [ Thread-3] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
英文:
In short: You are not using a spring managed context.
Let's walk through this together.
Assuming a class MyCoolClass
like:
@Component
public class MyCoolClass {
@Value("${some.value:3}")
private int a;
public void show() {
log.info("a is " + a);
}
}
If you autowire it and call show() it logs
> a is 3
Now let's create a test to verify it really works:
@SpringBootTest
public class MyTest {
@Autowired
private MyCoolClass myCoolClass;
@Test
public void lookAtMe() {
myCoolClass.show();
}
}
This initially throws a NPE, because this.myCoolClass
is null; a first hint on something not working properly. Let's just overcome this and instanciate myCoolClass
on ourselves:
this.myCoolClass = new MyCoolClass();
this.myCoolClass.show()
> a is 0
The clue here is, if you create a MyCoolClass instance on your own, there's nobody who parses the @Value
annotation and processes the expressions for you. It's just an ordinary POJO.
To fix that, one adds @RunWith(SpringJUnit4ClassRunner.class)
to the class and et viola, the log runs a whole Spring Application startup and logs a is 3
! (of course without the user-created constructor-call):
@SpringBootTest
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
public class mytest {
@Autowired
private MyCoolClass myCoolClass;
@Test
public void lookAtMe() {
myCoolClass.show();
}
}
And that's how the log looks:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.13.RELEASE)
12:41:59 INFO 912 --- [ main] com.example.demo.MyTest : Starting MyTest on clijsters-computer with PID 912 (started by dclijsters in C:\demo)
12:41:59 INFO 912 --- [ main] com.example.demo.MyTest : No active profile set, falling back to default profiles: default
12:42:01 INFO 912 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
12:42:02 INFO 912 --- [ main] o.s.s.c.ThreadPoolTaskScheduler : Initializing ExecutorService 'taskScheduler'
12:42:02 INFO 912 --- [ main] com.example.demo.MyTest : Started MyTest in 2.513 seconds (JVM running for 3.376)
12:42:02 INFO 912 --- [ main] com.example.demo.MyTest : a is 3
12:42:02 INFO 912 --- [ Thread-3] o.s.s.c.ThreadPoolTaskScheduler : Shutting down ExecutorService 'taskScheduler'
12:42:02 INFO 912 --- [ Thread-3] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论