我有一个简单的SpringBoot应用程序,我使用Environment.class
来访问application.properties
文件下的属性。在Environment
main
方法中访问Application.class
bean时,@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackages = "com.cisco.sdp.cdx.consumers")
public class StreamingConsumerApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(StreamingConsumerApplication.class, args);
Environment env = context.getBean(Environment.class);
StreamingConsumerFactory factory = context.getBean(StreamingConsumerFactory.class);
StreamingConsumer streamingConsumer = factory.createStreamingConsumer(StreamType.valueOf(env.getRequiredProperty("streaming.application.type")));
streamingConsumer.consume();
}
}
bean可以正常工作
NullPointerException
当在不同的类中使用它时,它会抛出@Configuration
。我尝试使用@Component
,@Repository
,@Service
,@Autowired
注释对该类进行注释,但无效。
我尝试了@Resource
以及@Component
public class InventoryStreamingConsumer implements StreamingConsumer {
@Autowired
private Environment env;
@Autowired
private JavaSparkSessionSingleton sparksession;
@Autowired
private StreamingContext _CONTEXT;
private final Map<String, String> kafkaParams = new HashMap<String, String>();
@Override
public void consume() {
if(env == null) {
System.out.println("ENV is NULL");
}
System.out.println(env.getRequiredProperty("kafka.brokerlist"));
kafkaParams.put("metadata.broker.list", env.getRequiredProperty("kafka.brokerlist"));
Set<String> topics = Collections.singleton(env.getRequiredProperty("kafka.topic"));
// Unrelated code.
}
注释。但是,它没有用。
mjs
我尝试按照以下问题提供的答案
Spring Boot - Environment @Autowired throws NullPointerException
我正在寻找解决问题的建议。
答案 0 :(得分:2)
这里@Configuration
注释被误用InventoryStreamingConsumer
。试试@Component
,@Repository
或@Service
。
更新
另一个误用是
StreamingConsumer streamingConsumer = factory.createStreamingConsumer(StreamType.valueOf(env.getRequiredProperty("streaming.application.type")));
@Autowired
或@Resource
只能在bean
创建的Spring
中使用。 streamingConsumer
创建的StreamingConsumerFactory factory
无法使用@Autowired
注入其属性。
您应该创建一个@Configuration
课程,告诉Spring
从您的工厂创建streamingConsumer
。喜欢这个
@Configuration
public class ConsumerCreator {
@Autowired
StreamingConsumerFactory factory;
@Bean
public StreamingConsumer streamingConsumer() {
return factory.createStreamingConsumer(StreamType.valueOf(env.getRequiredProperty("streaming.application.type")));
}
}
并且不使用InventoryStreamingConsumer
的注释,同时使用
StreamingConsumer streamingConsumer = context.getBean(StreamingConsumer.class);
在您的StreamingConsumerApplication.main()
方法中,而不是检索streamingConsumer
答案 1 :(得分:1)
首先,请仅使用@SpringBootApplication
@SpringBootApplication
public class StreamingConsumerApplication {
}
如果您的包与主类不在同一个结构中,则需要 @ComponentScan
,主类在子包之外,而在父包内,其中每个其他类在父包的相同或某个子包中
其次,请创建一个Configuration类并分别使用@Configuration
对其进行注释,并为@Bean
定义StreamingConsumer streamingConsumer
,而@Autowired
可以InventoryStreamingConsumer
或注入@Bean
{1}}上课。
第三, JavaSparkSessionSingleton 的InventoryStreamingConsumer
在哪里定义?你确定它可以自动配置注射
第四,@Component
可以是Environment
,只要对上述内容进行排序,注入@Autowiring
consume()
就可以了。
此外,建议根据使用@Component
public class InventoryStreamingConsumer implements StreamingConsumer {
private final Environment env;
private final JavaSparkSessionSingleton sparksession;
private final StreamingContext _CONTEXT;
private final Map<String, String> kafkaParams = new HashMap<String, String>();
@Autowired
public InventoryStreamingConsumer(Environment env, JavaSparkSessionSingleton sparkSession, StreamingContext context) {
this.env = env;
this.sparksession = sparkSession;
this._CONTEXT = context;
}
@Override
public void consume() {
if(env == null) {
System.out.println("ENV is NULL");
}
System.out.println(env.getRequiredProperty("kafka.brokerlist"));
kafkaParams.put("metadata.broker.list", env.getRequiredProperty("kafka.brokerlist"));
Set<String> topics = Collections.singleton(env.getRequiredProperty("kafka.topic"));
// Unrelated code.
}
方法的方式将您的课程更改为此。
Key Value Value2 Min Value Min Value2
1xA 1 2 1 2
2xA 2 3 2 3
3xB 3 1 2 2
1xB 1 1 1 1
1xA 5 5 1 2
2xB 2 6 2 6
3xB 2 2 2 2
2xA 4 1 2 3
答案 2 :(得分:0)
尝试添加
@PropertySource("classpath:application.properties")
这就是使用它的方式
@Configuration
@ComponentScan({ "com.spring.config" })
@EnableTransactionManagement
@PropertySource("classpath:application.properties")
public class HibernateConfiguration {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
@Autowired
private Environment env;
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return dataSource;
}
答案 3 :(得分:0)
我有类似的问题,但是从不同的文件和不同的位置(如 common / jdbc.properties )读取属性。我这样做可以解决这个问题:
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;
@Configuration
@PropertySource(value = {"classpath:common/jdbc.properties"})
public class ExternalConfig implements EnvironmentAware {
private Environment environment;
public void setEnvironment(Environment environment) {
this.environment = environment;
}
@Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
return new PropertySourcesPlaceholderConfigurer();
}
public String getJdbcUrl() {
return environment.getProperty("jdbc.url");
}
}