【发布时间】:2019-12-04 04:44:13
【问题描述】:
以下是spring boot项目的YML文件中的条目。
application:
applicationPath: "/demo"
defaultFilePath: ${application.applicationPath}childDemo/import_files/
actDocsPath: ${application.applicationPath}childDemo2/act_docs/
bgJobsLogs: ${application.applicationPath}childDemo3/bgjobs_logs/
在这些位置,我在我的项目中保存了一些文档。
要求是......在项目启动时我想创建所有这些目录结构,因此我创建了一个类......
package com.sbill.app.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "application", ignoreUnknownFields = false)
public class ApplicationProperties {
@Value("${application.applicationPath}")
public String applicationPath;
@Value("${application.defaultFilePath}")
public String defaultFilePath;
@Value("${application.actDocsPath}")
public String actDocsPath;
@Value("${application.bgJobsLogs}")
public String bgJobsLogs;
public String getDefaultFilePath() {
return defaultFilePath;
}
public void setDefaultFilePath(String defaultFilePath) {
this.defaultFilePath = defaultFilePath;
}
public String getActDocsPath() {
return actDocsPath;
}
public void setActDocsPath(String actDocsPath) {
this.actDocsPath = actDocsPath;
}
public String getBgJobsLogs() {
return bgJobsLogs;
}
public String getApplicationPath() {
return applicationPath;
}
public void setApplicationPath(String applicationPath) {
this.applicationPath = applicationPath;
}
}
我创建了一个类,我用CommandLineRunner 实现了在启动时调用
package com.sbill.app.config;
import java.io.File;
import java.lang.reflect.Field;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import com.sbill.app.domain.User;
import com.sbill.app.repository.UserRepository;
import com.sbill.app.service.util.FieldReqValidationUtil;
@Component
public class SbillStartupRunner implements CommandLineRunner {
@Autowired
ApplicationProperties applicationProperties;
@Override
public void run(String... args) throws Exception {
System.out.println(applicationProperties.getDefaultFilePath());
System.out.println(applicationProperties.getApplicationPath());
Field[] fields = applicationProperties.getClass().getDeclaredFields();
for(Field f : fields){
f.setAccessible(true);
Class t = f.getType();
Object v = f.get(applicationProperties);
File applicationpath = new File(v.toString());
if (!applicationpath.exists()) {
if (applicationpath.mkdirs()) {
System.out.println("Directory is created!");
} else {
System.out.println("Failed to create directory!");
}
}
System.out.println(applicationpath.getAbsolutePath());
}
}
}
我的问题是:- 使用 setter/getter 路径正在打印,但使用反射我无法访问字段..
【问题讨论】:
-
你为什么有
@Value? -
@chrylis-onstrike- 是的,值注释不应该存在......实际上这个类已经创建,只是我的任务是创建目录,但我不认为这个问题与值注释有关。 .. 使用 setter/getter 我可以访问值
-
属性(使用 getter/setter)不是
Field。由于Field是private,您无法访问它。接下来,您可能会得到一个代理类而不是实际类。但是为什么要使用反射呢?只是使用吸气剂而不是用反射来尝试这个?有什么收获? -
@M.Deinum 我需要遍历 ApplicationProperties.java 的所有字段,这就是为什么使用反射,而不使用 getter 的反射我该怎么做?
-
为什么?所有领域都有吸气剂......所以你为什么需要反射,没有吸气剂/设置器
@ConfigurationProperties将不起作用。看起来您正在尝试使用诸如反射之类的复杂事物来制作通用解决方案。如果你真的想使用反射(我建议不要这样做)是使用 SpringReflectionUtils.doWithFields方法并使用 lambda 表达式实现FieldFilter和FieldCallback。
标签: java spring-boot reflection