我正在开发一个Spring Boot应用程序。目前,我的一些配置是硬编码的(例如Hystrix属性)。
所以我想在应用程序启动时或刚启动后获取这些配置。
使用Spring Boot可以做到这一点吗?我的意思是在启动时运行SQL脚本并获取数据。
在我的应用程序中应该如何检索和存储propertiesconfigs?
我正在使用MyBatis和Oracle DB。
默认情况下,Spring-Boot会加载 data.sql
或 data-${platform}.sql
.
然而,请记住,脚本将在每次启动时加载,所以我认为更有意义的是(至少对生产而言),只是让数据库中已经存在的值,而不是在每次启动时重新插入。我个人在使用内存数据库时,只把数据库初始化用于testdev目的。 不过,这是Spring-Boot提供的功能。
来源:Spring-boot-howto-databate spring-boot-howto-database-initialization(数据库初始化):
Spring JDBC有一个DataSource初始化器功能。Spring Boot默认启用它,并从标准位置schema.sql和data.sql(在classpath的根目录下)加载SQL。此外,Spring Boot 还会加载 schema-${platform}.sql 和 data-${platform}.sql 文件(如果存在)。
srcmainresourcesdata-oracle.sql。
insert into...
insert into...
spring.datasource.platform=oracle
.spring.datasource.data=myscript.sql
.data.sql
,Spring-boot也会加载 schema.sql
(之前 data.sql
).对我有用的是使用 DataSourceInitializer
:
@Bean
public DataSourceInitializer dataSourceInitializer(@Qualifier("dataSource") final DataSource dataSource) {
ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator();
resourceDatabasePopulator.addScript(new ClassPathResource("/data.sql"));
DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
dataSourceInitializer.setDataSource(dataSource);
dataSourceInitializer.setDatabasePopulator(resourceDatabasePopulator);
return dataSourceInitializer;
}
用于在初始化时设置数据库,在销毁时清理数据库。
如果你想基于一些业务逻辑来插入数据,我建议你使用事件监听器。所以基本上在应用程序启动时,"OnApplicationEvent",因为它被注解为@EventListener方法将被自动调用。
另外,在你的案例中,你需要获取数据,你只需要使用你的仓库对象来获取数据即可。
这里有一个例子,如果你从application.properties文件中获取数据,那么你只需要使用你的仓库对象来获取数据。
@Component
public class OnApplicationStartUp {
@Autowired
private ServiceRepository repository;
@EventListener
public void onApplicationEvent(ContextRefreshedEvent event) {
//Write your business logic here.
if (repository.findAll().size() <= 0) {
preloadData();
}else{
fetchData();
}
}
private void preloadData() {
List<Service> services = new ArrayList<>();
Service someService= new Service("name", "type");
services.add(someService);
...
...
repository.saveAll(services);
}
}
如果你从application.properties文件中获取数据 你可以使用Environment类,就像这样。
Autowired
private Environment environment;
...
environment.getProperty("propertyName")
或者你可以定义你自己的属性文件,然后你可以用 @PropertySource(name = "myProperties", value = "example.properties")
注释
你需要使用@Value注解来从你定义的属性文件中获取一个特定的值。
@Value("${propertyNameInYourPropertFile}")
private String url;
如果你想在Application刚刚启动的时候启动一些东西,你可以在一个方法之前使用这个方法。
@EventListener(ApplicationReadyEvent.class)
但需要使用@Service或@Component Annotation,哪个Class有这个方法。
完全可以用这个方法。
example.properties :
url=yourValue
userName=yourDBUserName
password=yourDBPassword
example.properties : example类。
@Service
@PropertySource(name = "myProperties", value = "example.properties")
public class Start{
@Value("${url}")
private String url;
@Value("${userName}")
private String userName;
@Value("${password}")
private String password;
//Run this method when application started
@EventListener(ApplicationReadyEvent.class)
public ResultSet getConnection()
{
//Connect to Database
Connection connection = null;
String QUERY="your sql query";
try {
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
connection = DriverManager.getConnection(url, userName, password );
} catch (SQLException e) {
}
//Run your query
Statement stmt = null;
try {
stmt = connection.createStatement();
} catch (SQLException e1) {
e1.printStackTrace();
}
ResultSet rs = null;
try {
rs = stmt.executeQuery(QUERY);
} catch (SQLException e1) {
e1.printStackTrace();
}
return rs;
}
}
定义一个Spring Bean(例如GlobalConfigurationBean)的Scope。@Scope(scopeName = WebApplicationContext.SCOPE_APPLICATION) 这个Bean将负责在Bean初始化时从你的数据库表中获取数据(维护配置属性)。
使用 @PostConstruct 注释一个方法。 这个方法将具有从你的数据库表中获取配置参数的逻辑。
这个Bean的范围将确保所需的Configurations只从数据库表中获取一次(例如使用Hibernate查询或纯本地SQL),并且对同一应用程序中不同上下文的所有Bean都可用。
现在只需在您希望使用这些配置属性或参数的任何地方注入此Bean即可。 或者使用:。Apache Commons DatabaseConfiguration <-- 注意::它不支持缓存。但我想你不需要缓存,因为数据库配置属性应该只被加载一次,在应用程序启动时。 或者Trandational老方法。通过扩展 "PropertyPlaceHolderConfigurer "定义一个自定义实现,并将其定义为Spring Bean。这个实现应该有逻辑从你的数据库表中获取数据,该表拥有配置属性。
当只使用基本 SQL 脚本时,Spring Boot 会自动创建嵌入式 DataSource 的模式。这种行为可以通过使用 spring.datasource.initialization-mode 属性进行自定义。例如,如果您希望始终初始化 DataSource,而不管其类型如何。
spring.datasource.initialization-mode=always