Spring Mvc - 创建自定义注释以从数据库中读取应用程序属性
Posted
技术标签:
【中文标题】Spring Mvc - 创建自定义注释以从数据库中读取应用程序属性【英文标题】:Spring Mvc - Creating Custom Annotation For Reading Application Properties From Database 【发布时间】:2019-12-31 13:11:57 【问题描述】:我开发了 Spring-Mvc 项目,这个项目的应用属性太重要了。此外,我无法在程序运行期间更改此属性。所以,我想从数据库中获取这些属性并分配给类的成员。
现在,我使用服务从数据库中获取这些属性,但我不认为,这段代码是可重用的。我想知道,是否有任何方法可以通过自定义注释将此属性提供给成员?
ApplicationPropertiesDao.java
@Repository
public class ApplicationPropertiesDao implements IApplicationPropertiesDao
@Value("#appProperties.instanceName")
private String instanceName;
@Override
@Cacheable("applicationProperties")
public HashMap<String, String> getApplicationPropertiesFromDB()
Map<String, Object> inputMap = new HashMap<String, Object>();
inputMap.put("instanceName", instanceName);
String sql = getSQL("getApplicationProperties");
Map<String, String> list = new HashMap<String, String>();
getNamedParameterJdbcTemplate().query(sql, inputMap, new ResultSetExtractor<Map<String, String>>()
@Override
public Map<String, String> extractData(ResultSet resultSet) throws SQLException, DataAccessException
while (resultSet.next())
list.put( resultSet.getString("NAME"),resultSet.getString("VALUE"));
return list;
);
return (HashMap<String, String>) list;
ApplicationPropertiesService.java
@Service
public class ApplicationPropertiesService implements IApplicationPropertiesService
@Autowired
private IApplicationPropertiesDao applicationPropertiesDao;
public HashMap<String, String> getApplicationPropertiesFromDB()
return applicationPropertiesDao.getApplicationPropertiesFromDB();
public Object getApplicationPropertyByName(String name, ApplicationPropertyValueTypeEnum applicationPropertyValueTypeEnum)
String value = getApplicationPropertiesFromDB().get(name);
if (applicationPropertyValueTypeEnum.name().equals(ApplicationPropertyValueTypeEnum.INTEGER.toString()))
return Integer.parseInt(value);
else if(applicationPropertyValueTypeEnum.name().equals(ApplicationPropertyValueTypeEnum.BOOLEAN.toString()))
String upperCaseValue = value.toUpperCase(Locale.ENGLISH);
return upperCaseValue.equals("TRUE") ? Boolean.TRUE : Boolean.FALSE;
return value;
我可以为这种情况创建如下所示的自定义注释吗?如果有,我会很高兴。我怎么能做这个?
@Service
public class Demo
private String val;
@Autowired
public ApplicationPropertiesService applicationPropertiesService;
@GetPropertyFromDB(key = "val", type = "String")
public getVal()
//set(applicationPropertiesService.getApplicationPropertyByName("val", "String"));
return this.val;
public void setVal(String val)
this.val = val;
感谢您的帮助。
【问题讨论】:
【参考方案1】:我认为您需要 DB PropertyPlaceholderConfigurer。 像这样的东西: Spring PropertyPlaceholderConfigurer load from DB
如果您集成自定义 DB PropertyPlaceholderConfigurer。 (见https://www.baeldung.com/properties-with-spring)
@Bean
public static PropertySourcesPlaceholderConfigurer properties()
return new MyDBPlaceholderConfigurer();
您将能够使用标准的@Value 和@ConfigurationProperties 注释。
【讨论】:
【参考方案2】:我在开始时使用这个类来配置属性,但我无法在特定时间段从数据库中加载这些属性。此类作品仅开始。我可以在不重新启动程序的情况下每分钟调用一次这个 loadProperties 方法吗?
DbPropertyPlaceholderConfigurer.java
@Service
public class DbPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer
private DataSource dataSource;
private String key = "NAME";
private String value = "VALUE";
private String table = "APPLICATION_PROPERTIES";
private String instanceName;
@Override
protected void loadProperties(final Properties props) throws IOException
if (null == props)
throw new IOException("No properties passed by Spring framework - cannot proceed.");
String sql = String.format("SELECT %s, %s FROM %s where INSTANCE_NAME = '%s'", key, value,
table, instanceName);
try
JdbcTemplate t = new JdbcTemplate(dataSource);
t.query(sql, new RowCallbackHandler()
@Override
public void processRow(ResultSet rs) throws SQLException
String auxKey = rs.getString(key);
String auxValue = rs.getString(value);
if (null == auxKey || null == auxValue)
throw new SQLException("Configuration database contains empty data. Name='" + (auxKey == null ? "" : auxKey)
+ "', Value='" + (auxValue == null ? "" : auxValue) + "'.");
props.setProperty(auxKey, auxValue);
);
catch (Exception e)
logger.error("There is an error in the configuration database.");
throw new IOException(e);
if (props.size() == 0)
logger.error("The configuration database could not be reached or does not contain any properties in '" + table
+ "'.");
else
logger.info("Application config info loaded from configuration database.");
public void setDataSource(DataSource dataSource)
this.dataSource = dataSource;
public void setInstanceName(String instanceName)
this.instanceName = instanceName;
applicationContext.xml
<bean id="placeholderPropertiesDatabase" class="com.common.DbPropertyPlaceholderConfigurer" >
<property name="dataSource" ref="dataSource" />
<property name="instanceName" value="instance1" />
<property name="placeholderPrefix" value="$db" />
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreUnresolvablePlaceholders" value="false" />
<property name="order" value="1" />
</bean>
【讨论】:
以上是关于Spring Mvc - 创建自定义注释以从数据库中读取应用程序属性的主要内容,如果未能解决你的问题,请参考以下文章
Gradle 如何配置构建文件以从同一项目创建 Spring boot jar 和 spring web-mvc war