在静态初始值设定项块中加载java属性

在静态初始值设定项块中加载java属性,java,properties,Java,Properties,我有一个静态util类,它对一些敏感数据进行字符串操作。 在使用这个类之前,我需要用我喜欢存储在.properties文件中的值(例如用户名/密码)初始化某些静态变量 我不太熟悉在Java中加载.properties文件是如何工作的,尤其是在*springdi*容器之外。 任何人都可以帮助我/了解如何做到这一点 谢谢大家! 添加:.properties文件的精确位置未知,但它将位于类路径上。排序类似于classpath:/my/folder/name/myproperties.propertie

我有一个静态util类,它对一些敏感数据进行字符串操作。 在使用这个类之前,我需要用我喜欢存储在
.properties
文件中的值(例如用户名/密码)初始化某些静态变量

我不太熟悉在Java中加载
.properties
文件是如何工作的,尤其是在*springdi*容器之外。 任何人都可以帮助我/了解如何做到这一点

谢谢大家!

添加:
.properties
文件的精确位置未知,但它将位于类路径上。排序类似于
classpath:/my/folder/name/myproperties.properties

  • 退房

  • 可以使用静态初始值设定项。因此,在课程的顶端,你可以做:

  • 使用以下任一选项:

    CurrentClassName.class.getResourceAsStream 
    new FileInputStream(File)
    
    根据类在类路径中还是在类路径外获取输入流。然后使用

    Properties.load
    

    加载属性。

    已经有一段时间了,但如果我没记错的话,您可以这样做:

    Properties prop = new Properties();
    prop.load(new FileInputStream(filename));
    
    //For each property you need.
    blah = prop.getProperty(propertyname);
    
    private static final String NAME = "my.properties";
    
    private static final Properties config;
    
    static {
      Properties fallback = new Properties();
      fallback.put("key", "default");
      config = new Properties(fallback);
    
      URL res = MyClass.getResource(NAME);
      if (res == null) throw new UncheckedIOException(new FileNotFoundException(NAME));
      URI uri;
      try { uri = res.toURI(); }
      catch (URISyntaxException ex) { throw new IllegalArgumentException(ex); }
    
      try (InputStream is = Files.newInputStream(Paths.get(uri))) { config.load(is); } 
      catch (IOException ex) { throw new UncheckedIOException("Failed to load resource", ex); }
    }
    
    ConfigsLoader configsLoader = ConfigsLoader.getInstance("etc/configs.xml");
    
    System.out.format("source dir %s %n", configsLoader.getSourceDir());
    

    对于静态属性,将它们初始化为一个在类中加载一次的单例是有意义的。下面是一个例子:

    class Example
    {
        public final static String PROPSFILE = "test.properties";
    
        private static Properties props;
    
        protected static Properties getProperties()
        {
            if(props == null)
            {
                props = new Properties();
                props.load(new FileInputStream(new File(PROPSFILE));
            }
            return props;
        }
    
        public static User getUser()
        {
            String username = getProperties().getProperty("username");
            return new User(username);
        }
    }
    

    如果使用相对路径名,则应确保类路径已正确设置。

    首先,获取要从中加载属性的
    InputStream
    。这可能来自多个位置,包括一些最可能的位置:

    • A,使用硬编码或通过指定的文件名创建。该文件名可以是相对的(相对于Java进程的当前工作目录)或绝对的
    • 资源文件(类路径上的文件),通过调用(相对于类文件)或(相对于类路径的根)上的
      getResourceAsStream
      获得。请注意,如果资源丢失,这些方法将返回null,而不是引发异常
    • 与文件名类似,可以硬编码或通过系统属性指定
    然后创建一个新的
    Properties
    对象,并将
    InputStream
    传递给它的方法。不管有什么异常,请确保关闭流

    在类初始值设定项中,必须处理检查过的异常,如
    IOException
    。可以引发未检查的异常,这将阻止初始化该类。这反过来通常会阻止应用程序运行。在许多应用程序中,可能希望改用默认属性,或者回退到另一个配置源,例如在交互上下文中提示使用

    总之,它可能看起来像这样:

    Properties prop = new Properties();
    prop.load(new FileInputStream(filename));
    
    //For each property you need.
    blah = prop.getProperty(propertyname);
    
    private static final String NAME = "my.properties";
    
    private static final Properties config;
    
    static {
      Properties fallback = new Properties();
      fallback.put("key", "default");
      config = new Properties(fallback);
    
      URL res = MyClass.getResource(NAME);
      if (res == null) throw new UncheckedIOException(new FileNotFoundException(NAME));
      URI uri;
      try { uri = res.toURI(); }
      catch (URISyntaxException ex) { throw new IllegalArgumentException(ex); }
    
      try (InputStream is = Files.newInputStream(Paths.get(uri))) { config.load(is); } 
      catch (IOException ex) { throw new UncheckedIOException("Failed to load resource", ex); }
    }
    
    ConfigsLoader configsLoader = ConfigsLoader.getInstance("etc/configs.xml");
    
    System.out.format("source dir %s %n", configsLoader.getSourceDir());
    

    我同意@Daff,也许最好使用singleton类…这是我在项目中针对类似要求所做的工作,可能会有帮助:

    该类的客户端可以这样使用它:

    Properties prop = new Properties();
    prop.load(new FileInputStream(filename));
    
    //For each property you need.
    blah = prop.getProperty(propertyname);
    
    private static final String NAME = "my.properties";
    
    private static final Properties config;
    
    static {
      Properties fallback = new Properties();
      fallback.put("key", "default");
      config = new Properties(fallback);
    
      URL res = MyClass.getResource(NAME);
      if (res == null) throw new UncheckedIOException(new FileNotFoundException(NAME));
      URI uri;
      try { uri = res.toURI(); }
      catch (URISyntaxException ex) { throw new IllegalArgumentException(ex); }
    
      try (InputStream is = Files.newInputStream(Paths.get(uri))) { config.load(is); } 
      catch (IOException ex) { throw new UncheckedIOException("Failed to load resource", ex); }
    }
    
    ConfigsLoader configsLoader = ConfigsLoader.getInstance("etc/configs.xml");
    
    System.out.format("source dir %s %n", configsLoader.getSourceDir());
    
    然后是课堂:

    公共类配置加载程序{

    private String sourceDir;
    private String destination;
    private String activeMqUrl;
    
    private static Logger log = Logger.getLogger(ConfigsLoader.class.getName());
    
    private static ConfigsLoader instance = null;
    
    private ConfigsLoader(String configFileName) {
        log.info("loading configs");
        Properties configs = new Properties();
        try {
            configs.loadFromXML(new FileInputStream(configFileName));
    
            sourceDir = configs.getProperty("source.dir");
            destination = configs.getProperty("destination");
            activeMqUrl = configs.getProperty("activemqconnectionurl");
            configs.setProperty("lastLoaded", new SimpleDateFormat("yyyy-M-d HH:mm").format(new Date()));
            configs.storeToXML(new FileOutputStream(configFileName), "saving last modified dates");
    
        } catch (InvalidPropertiesFormatException e) {
            log.log(Level.SEVERE,"Error occured loading the properties file" ,e);
        } catch (FileNotFoundException e) {
            log.log(Level.SEVERE,"Error occured loading the properties file" ,e);
        } catch (IOException e) {
            log.log(Level.SEVERE,"Error occured loading the properties file" ,e);
        }
    }
    
    public static ConfigsLoader getInstance(String configFileName) {
        if(instance ==null) {
            instance = new ConfigsLoader(configFileName);
        }
    
        return instance;
    }
    
    public String getSourceDir() {
        return sourceDir;
    }
    
    public void setSourceDir(String sourceDir) {
        this.sourceDir = sourceDir;
    }
    
    public String getDestination() {
        return destination;
    }
    
    public void setDestination(String destination) {
        this.destination = destination;
    }
    
    public String getActiveMqUrl() {
        return activeMqUrl;
    }
    
    public void setActiveMqUrl(String activeMqUrl) {
        this.activeMqUrl = activeMqUrl;
    }
    

    }

    最后,我使用与编写静态代码块的类相关联的getResourceAsStream()函数完成了这项工作

    //associate Property and ImputStream imports
    public class A {
        static Properties p;
        static {
          p = new Properties();
          try {
              InputStream in = A.class.getResourceAsStream("filename.properties");
              p.load(in);
          } catch (FileNotFoundException e) {
            System.out.println("FileNotFoundException");
            e.printStackTrace();
          } catch (IOException e) {
            System.out.println("IOException");
            e.printStackTrace();
          }
        }
        .
        .
        .
    }
    

    对我来说,
    MyClass.class.getClassLoader().getResourceAsStream(…)
    做到了这一点:

    private static final Properties properties;
    
    static {
        Properties fallback = new Properties();
        fallback.put(PROP_KEY, FALLBACK_VALUE);
    
        properties = new Properties(fallback);
    
        try {
            try (InputStream stream = MyClass.class.getClassLoader().getResourceAsStream("myProperties.properties")) {
                properties.load(stream);
            }
        } catch (IOException ex) {
            // handle error
        }
    }
    

    您提到了Spring——您是否在应用程序中使用了包含此静态实用程序类的框架?嗯,这有点奇怪。类将在使用spring容器的应用程序中使用。然而,类本身不会使用spring连接,它只需要是一个静态实用程序类,由spring连接的工作线程调用get。我可以修改工作线程,但我不能修改这些线程的连接(因此我不能使用PropertyPlaceHolderConfigure)…嗯,这有什么意义吗?:)抱歉,我猜您在我执行此操作时已经在格式化代码。您可能需要一些异常处理,因为我认为不能从静态块中引发异常。RuntimeExceptions可以从静态块中引发。您需要处理文件操作的已检查异常。此处建议的实现主要用于说明。为了提高生产质量,您需要处理与文件相关的异常(例如,安全性、存在性、IOException)、在finally块中关闭连接、处理加密(我希望他不会以明文形式保存密码),等等,这不是一个单一的问题。它只是一个静态变量和方法。这个问题不需要公共访问属性,而是需要从属性文件初始化静态成员。就我个人而言,我不喜欢静态初始化,因为它在我正在进行的项目中造成了一些麻烦。我建议在可能的情况下至少使用静态工厂方法(为此我更新了示例)。但事实上,这并不是问题所在。