代码之家  ›  专栏  ›  技术社区  ›  Adi Sembiring

如何构建自己的应用程序设置

  •  1
  • Adi Sembiring  · 技术社区  · 15 年前

    我想建一个 ApplicationSetting 为我的申请。这个 应用程序设置 可以存储在属性文件或数据库表中。这些设置存储在键值对中。例如。

    ftp.host = blade
    ftp.username = dummy
    ftp.pass = pass
    content.row_pagination = 20
    content.title = How to train your dragon.
    

    我设计如下:

    应用程序设置读卡器:

        interface IApplicationSettingReader {
        Map read();
    }
    
    DatabaseApplicationSettingReader implements IApplicationSettingReader {
        dao appSettingDao;
    
        Map read() {
            List<AppSettingEntity> listEntity = appSettingsDao.findAll();
            Map<String, String> map = new HaspMap<String, String>();
            foreach (AppSettingEntity entity : listEntity) {
                map.put(entity.getConfigName(), entity.getConfigValue());
            }
    
            return new AppSettings(map);
        }
    }
    
    DatabaseApplicationSettingReader implements IApplicationSettingReader {
        dao appSettingDao;
    
        Map read() {
            //read from some properties file 
            return new AppSettings(map);
        }
    }
    

    应用程序设置类:

    AppSettings {
    private static AppSettings instance = new AppSettings();
    private Map map;
    
    private AppSettings() {
    }
    
    
    
    public static AppSettings getInstance() {
        if (instance == null) {
            throw new RuntimeException("Object not configure yet");
        } 
    
        return instance;
    }
    
    public static configure(IApplicationSettingReader reader) {
        this.map = reader.read();
    
    }
    
    public String getFtpSetting(String param) {
        return map.get("ftp." + param);
    }
    
    public String getContentSetting(String param) {
        return map.get("content." + param);
    }
    

    }

    测试类:

    AppSettingsTest {
        IApplicationSettingReader reader;
    
        @Before
        public void setUp() throws Exception {
            reader = new DatabaseApplicationSettingReader();
        }
    
        @Test
        public void  getContentSetting_should_get_content_title() {
            AppSettings.configure(reader);
    
            Instance settings = AppSettings.getInstance();
            String title = settings.getContentSetting("title");
            assertNotNull(title);
            Sysout(title);
        }
    
    }
    

    我的问题是:

    1. 你能对我的代码给出你的意见吗,有什么问题吗???????

    2. 我配置了一次应用程序设置,当应用程序启动时,我用适当的读卡器配置应用程序设置。( DbReader PropertiesReader ,我将其设置为singleton,因为应用程序只有一个applicationsettings实例。问题是,当某些用户直接将数据库或文件编辑到数据库或文件时,我无法获取更改的值。现在,我想实现 ApplicationSettingChangeListener . 因此,如果数据发生更改,我将刷新应用程序设置。你对如何实现这一点有什么建议吗?????

    2 回复  |  直到 15 年前
        1
  •  0
  •   Enno Shioji    15 年前

    我还没有彻底检查您的代码,但似乎存在并发问题。映射是线程不安全的(hashmap),因此如果您通过config()改变它并让其他线程访问映射,则会出现问题。

    尽管你可以用 ConcurrentHashMap 相反 HashMap ,上的批处理操作 当前地图 不是原子的。也就是说,如果使用它,您将看到一个“中途”修改的配置。根据你的应用程序,这可能不太好。

    因此,解决这个问题的方法是使用这个:

    private volatile ImmutableMap map;
    
    public config(){
        ImmutableMap newMap = createNewMap();
        this.map = newMap;
    }
    

    这将自动改变您的配置(中间状态不可见)。

    至于动态更新配置,log4j使用一个后台线程来监视配置文件。当然,您可以通过定期轮询来监控DB表。

    在这种情况下,您的config类最好有一个scheduledexecutor,其任务将监视文件/db并定期调用config()。

        2
  •  0
  •   Jan K.    15 年前

    问题2的答案是使用线程并定期检查文件是否已更改,或者只需使用文件内容重新初始化设置。