package com.walker.infrastructure.arguments; import com.walker.infrastructure.core.NestedRuntimeException; import com.walker.infrastructure.utils.FileCopyUtils; import com.walker.infrastructure.utils.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.FactoryBean; import org.springframework.core.io.ClassPathResource; import java.io.File; import java.io.IOException; /** * 可以通过各种方式(XML配置文件、数据库)等来生成系统配置选项管理对象。
* 目前仅使用XML配置文件,可扩展。 * @author shikeying * @date 2014-5-27 * */ public class ArgumentsManagerFactoryBean implements FactoryBean { private final Logger logger = LoggerFactory.getLogger(getClass()); public static final String DEFAULT_CONFIG_FILENAME = "app_variables"; private ArgumentsManager defaultArgumentManager; // 暂时未使用 private String filename; private String suffix = StringUtils.EMPTY_STRING; /* 是否启动配置文件,在classpath中查找,默认启动,如果不启动则配置文件会拷贝到临时目录中 */ private boolean openClasspath = true; public void setOpenClasspath(boolean openClasspath) { this.openClasspath = openClasspath; } /** * 设置app_variable.xml后缀名,防止多个相同项目部署出现配置不一致问题 * @param suffix */ public void setSuffix(String suffix) { this.suffix = suffix; } @Override public ArgumentsManager getObject() throws Exception { if(defaultArgumentManager != null){ return defaultArgumentManager; } if(StringUtils.isNotEmpty(filename)){ defaultArgumentManager = ArgumentsManagerFactory.createXmlArgumentsManager(filename, false); } else { if(!openClasspath){ // 默认都使用绝对文件路径,因为tomcat等容器会检测到文件发生变化时重启服务,所以放在容器之外就可以了。 String absoluteFilename = System.getProperty("java.io.tmpdir") + DEFAULT_CONFIG_FILENAME + suffix + ".xml"; logger.info("------------- ArgumentsManager配置文件: " + absoluteFilename); doCheckExist(absoluteFilename); defaultArgumentManager = ArgumentsManagerFactory.createXmlArgumentsManager(absoluteFilename, false); } else { String classpathFile = DEFAULT_CONFIG_FILENAME + ".xml"; logger.info("------------- ArgumentsManager配置文件在classpath中: " + classpathFile); defaultArgumentManager = ArgumentsManagerFactory.createXmlArgumentsManager(classpathFile, true); } } return defaultArgumentManager; } /** * 判断variable.xml配置文件,在临时文件夹中是否存在。
* 如果已存在检查更新,如果原始文件更新过就覆盖,确保临时文件最新。
* 如果不存在就拷贝到临时文件夹。 * @param filepath */ private void doCheckExist(String filepath){ File file = new File(filepath); org.springframework.core.io.ClassPathResource defaultVariableSource = new ClassPathResource(DEFAULT_CONFIG_FILENAME + ".xml"); if(!file.exists()){ // 不存在需要把默认variable.xml文件拷贝到目的路径中。 try { file.createNewFile(); FileCopyUtils.copy(defaultVariableSource.getFile(), file); logger.debug("创建variable配置文件成功: " + filepath); } catch (IOException e) { logger.error("创建可变参数配置文件出现错误", e); throw new NestedRuntimeException(filepath); } } else { // 如果存在文件,比较时间戳,看是否存在变化 long destFileModified = file.lastModified(); long srcFileModified = 0; try { srcFileModified = defaultVariableSource.getFile().lastModified(); logger.debug("variable文件原始时间: " + srcFileModified + ", 目的文件修改时间: " + destFileModified); if(srcFileModified > destFileModified){ logger.debug("原始配置文件变化,重新覆盖目的文件"); FileCopyUtils.copy(defaultVariableSource.getFile(), file); } } catch (IOException e) { throw new NestedRuntimeException(e.getMessage()); } } } @Override public Class getObjectType() { return ArgumentsManager.class; } @Override public boolean isSingleton() { return true; } /** * 对于使用xml文件作为存储配置信息时,可以设置classpath下面的文件名,
* 应用配置参数会被持久到此文件中。 * @param filename */ public void setFilename(String filename){ this.filename = filename; } }