@Java类中的值注释don';t从.properties文件加载值
在提出这个问题之前,我试着回答以下类似的问题: 然而,就我而言,我没有使用任何web应用程序或Tomcat;我只是尝试通过Spring将cluster.properties文件加载到一个常规Java项目中,这样我就可以将虚拟数据摄取到Accumulo中。另外,我试图从cluster.properties文件加载属性,而不是从xml文件中定义的键值对加载属性 利用我从上面的链接中学到的知识和大量有关Spring的阅读资料,以下是我所掌握的: 我创建了以下context.xml文件:@Java类中的值注释don';t从.properties文件加载值,java,spring,properties,annotations,accumulo,Java,Spring,Properties,Annotations,Accumulo,在提出这个问题之前,我试着回答以下类似的问题: 然而,就我而言,我没有使用任何web应用程序或Tomcat;我只是尝试通过Spring将cluster.properties文件加载到一个常规Java项目中,这样我就可以将虚拟数据摄取到Accumulo中。另外,我试图从cluster.properties文件加载属性,而不是从xml文件中定义的键值对加载属性 利用我从上面的链接中学到的知识和大量有关Spring的阅读资料,以下是我所掌握的: 我创建了以下context.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<!-- Define the Spring Bean to load our cluster properties -->
<bean id="props" class="accumuloIngest.LoadProperties"></bean>
</beans>
接下来,我在MainApp.java类下创建了以下Spring main方法:
package accumuloIngest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
// Spring main method used to load a cluster.properties file with the Spring framework
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("context.xml");
LoadProperties myObj = LoadProperties.class.cast(ctx.getBean("props"));
// Now print out the cluster.properties loaded by Spring to verify they aren't null
StringBuffer springPropsBuffer = new StringBuffer();
springPropsBuffer.append("Printing out cluster.properties read via Spring...");
springPropsBuffer.append("\n\n");
springPropsBuffer.append("instanceName= ");
springPropsBuffer.append(myObj.getInstanceName());
springPropsBuffer.append("\n");
springPropsBuffer.append("userName= ");
springPropsBuffer.append(myObj.getUserName());
springPropsBuffer.append("\n");
springPropsBuffer.append("password= ");
springPropsBuffer.append(myObj.getPassword());
springPropsBuffer.append("\n");
springPropsBuffer.append("zooServers= ");
springPropsBuffer.append(myObj.getZooServers());
springPropsBuffer.append("\n");
springPropsBuffer.append("tableName= ");
springPropsBuffer.append(myObj.getTableName());
springPropsBuffer.append("\n");
springPropsBuffer.append("dataFile= ");
springPropsBuffer.append(myObj.getDataFile());
springPropsBuffer.append("\n");
springPropsBuffer.append("dataDelim= ");
springPropsBuffer.append(myObj.getDataDelim());
springPropsBuffer.append("\n");
springPropsBuffer.append("rowCount= ");
springPropsBuffer.append(myObj.getRowCount());
springPropsBuffer.append("\n");
System.out.println(springPropsBuffer.toString());
// now start data ingest
myObj.startIngest(); // method that calls Ingester class to start data ingest
} // end of main method
} // end of MainApp class
Spring加载我的context.xml文件并加载我称为“props”的Bean,但值仍然为null。似乎我的@Value注释在我的LoadProperties类中不起作用:
package accumuloIngest;
import java.io.IOException;
import org.apache.accumulo.core.client.AccumuloException;
import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.client.TableExistsException;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class LoadProperties {
// this class defines the Spring Bean and loads the cluster properties
// using the SpringFramework
@Bean
public static PropertyPlaceholderConfigurer props(){
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
Resource[] resource = new ClassPathResource[ ]
{ new ClassPathResource("/EclipseProjectName/src/cluster.properties") };
ppc.setLocations(resource);
ppc.setIgnoreUnresolvablePlaceholders(true);
return ppc;
}
// Now load the properties from cluster.properties using the Spring Framework
private @Value("${cluster.instance}") String instanceName;
private @Value("${cluster.username}") String userName;
private @Value("${cluster.password}") String password;
private @Value("${cluster.zooServers}") String zooServers;
private @Value("${cluster.TableName}") String tableName;
private @Value("${cluster.DataFile}") String dataFile;
private @Value("${cluster.DataDelimiter}") String dataDelim;
private @Value("${cluster.rowCount}") int rowCount;
// Getters for the other Java classes to access properties loaded by Spring
public String getInstanceName() {
return instanceName;
}
public String getUserName() {
return userName;
}
public String getPassword() {
return password;
}
public String getZooServers() {
return zooServers;
}
public String getTableName() {
return tableName;
}
public String getDataFile() {
return dataFile;
}
public String getDataDelim() {
return dataDelim;
}
public int getRowCount() {
return rowCount;
}
// method to kick off the ingest of dummy data
void startIngest() {
Ingester ingestObject = new Ingester();
try {
ingestObject.ingestData();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TableNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TableExistsException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (AccumuloException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (AccumuloSecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // end of try-catch block
} // end of startIngest method
} // end of LoadProperties class
然而,当我在Eclipse中运行MainApp.java时,当我的Ingester.java类调用getter时,这些值为null
以下是我在Eclipse中运行MainApp.java时的控制台输出:
13/09/24 14:08:24 INFO support.ClassPathXmlApplicationContext: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@191f667c: startup date [Tue Sep 24 14:08:24 EDT 2013]; root of context hierarchy
13/09/24 14:08:24 INFO xml.XmlBeanDefinitionReader: Loading XML bean definitions from class path resource [context.xml]
13/09/24 14:08:24 INFO support.DefaultListableBeanFactory: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3cdd17f5: defining beans [props]; root of factory hierarchy
Printing out cluster.properties read via Spring...
instanceName= null
userName= null
password= null
zooServers= null
tableName= null
dataFile= null
dataDelim= null
rowCount= 0
Exception in thread "main" java.lang.IllegalArgumentException: argument was null:Is null- arg1? true arg2? true
at org.apache.accumulo.core.util.ArgumentChecker.notNull(ArgumentChecker.java:36)
at org.apache.accumulo.core.client.ZooKeeperInstance.<init>(ZooKeeperInstance.java:99)
at org.apache.accumulo.core.client.ZooKeeperInstance.<init>(ZooKeeperInstance.java:85)
at accumuloIngest.Ingester.ingestData(Ingester.java:65)
at accumuloIngest.LoadProperties.startIngest(LoadProperties.java:69)
at accumuloIngest.MainApp.main(MainApp.java:44)
13/09/24 14:08:24信息支持.ClassPathXmlApplicationContext:刷新org.springframework.context.support。ClassPathXmlApplicationContext@191f667c:启动日期[美国东部夏令时2013年9月24日星期二14:08:24];上下文层次结构的根
13/09/24 14:08:24 INFO xml.XmlBeanDefinitionReader:从类路径资源[context.xml]加载xml bean定义
13/09/24 14:08:24 INFO support.DefaultListableBeanFactory:在org.springframework.beans.factory.support中预实例化单例。DefaultListableBeanFactory@3cdd17f5:定义bean[道具];工厂层次结构的根
正在打印通过Spring读取的cluster.properties。。。
instanceName=null
用户名=null
密码=null
zooServers=null
tableName=null
数据文件=null
dataDelim=null
行计数=0
线程“main”java.lang.IllegalArgumentException中的异常:参数为null:是否为null-arg1?真的arg2?真的
位于org.apache.accumulo.core.util.ArgumentChecker.notNull(ArgumentChecker.java:36)
位于org.apache.accumulo.core.client.ZooKeeperInstance.(ZooKeeperInstance.java:99)
位于org.apache.accumulo.core.client.ZooKeeperInstance.(ZooKeeperInstance.java:85)
位于accumuloIngest.Ingester.ingestData(Ingester.java:65)
在accumuloIngest.LoadProperties.startIngest(LoadProperties.java:69)
位于accumuloIngest.MainApp.main(MainApp.java:44)
我是否缺少加载cluster.properties文件中属性的Spring框架的一部分?我曾尝试将@AutoWired添加到我的MainApp和LoadProperties java类中,但似乎没有帮助。如果要使用
@Bean
,则需要@Configuration
。您不应该声明包含注释上下文的xml上下文。您也不应该将@Configuration
类实例用作beanClassPathXmlApplicationContext
不适合处理基于注释的配置
使用类似以下的方法
@Configuration
@ComponentScan(basePackageClasses = LoadProperties.class)
public static class Config {
@Bean
public static PropertyPlaceholderConfigurer props() {
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
Resource[] resource = new ClassPathResource[] { new ClassPathResource(
"/EclipseProjectName/src/cluster.properties") };
ppc.setLocations(resource);
ppc.setIgnoreUnresolvablePlaceholders(true);
return ppc;
}
@Bean
public LoadProperties loadProperties() {
return new LoadProperties();
}
}
public static class LoadProperties {
private @Value("${cluster.zooServers}") String zooServers;
... // getters and setters
}
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
LoadProperties load = (LoadProperties) context.getBean(LoadProperties.class);
System.out.println(load.getZooServers());
}
需要注意的几点:
类路径资源中
需要指定类路径资源。在类路径的根目录下是否真的有一个resource/EclipseProjectName/src/cluster.properties
?我非常怀疑@ComponentScan
,而是要熟悉它propertyplaceholderconfigure
需要声明为静态,以便在其他@Bean
声明之前对其进行初始化。您应该使用propertysourcesplaceplaceconfigurer
as这里有很多问题。首先,当您使用3.0中引入的
@Bean
时,为什么您的上下文名称空间声明SpringBeans版本2.0?是的,这是我的复制/粘贴错误。我在pom.xml中定义了SpringFramework 3.2.4,所以我修改了context.xml以使用SpringBeans版本3.2是的,你是对的,我的类路径根上没有资源。我阅读了SpringAPI中有关ClassPathResource的内容,也就是说,我意识到我应该在上面指定一个java类。但是我如何确定要指定哪个ClassPathResource呢?@user2160928这里我假设您需要一个.properties
文件,所以请指定该文件的路径。你需要弄清楚你的程序是如何编译和构建的,以弄清楚这个路径是什么或者应该是什么。我的cluster.properties文件位于我的Eclipse项目(上面我称之为EclipseProjectName)@user2160928下的src目录下。它可能在您的文件系统中,但Eclipse在bin
文件夹(afaik)中构建您的应用程序。另外,如果您从war
文件运行它,您认为它会在哪里呢?我在Eclipse项目的属性菜单下,在Java构建路径下,它在我的构建路径上包含了源文件夹/src。此外,我尝试了您在上面建议的代码更改,但似乎找不到我的cluster.properties文件。
@Configuration
@ComponentScan(basePackageClasses = LoadProperties.class)
public static class Config {
@Bean
public static PropertyPlaceholderConfigurer props() {
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
Resource[] resource = new ClassPathResource[] { new ClassPathResource(
"/EclipseProjectName/src/cluster.properties") };
ppc.setLocations(resource);
ppc.setIgnoreUnresolvablePlaceholders(true);
return ppc;
}
@Bean
public LoadProperties loadProperties() {
return new LoadProperties();
}
}
public static class LoadProperties {
private @Value("${cluster.zooServers}") String zooServers;
... // getters and setters
}
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
LoadProperties load = (LoadProperties) context.getBean(LoadProperties.class);
System.out.println(load.getZooServers());
}