![](/img/trans.png)
[英]Spring Boot - Environment @Autowired throws NullPointerException
[英]Spring Boot @Autowired Environment throws NullPointerException
我有一個簡單的 SpringBoot 應用程序,我在其中使用Environment.class
訪問application.properties
文件下的屬性。 Environment
bean 在Application.class
的main
方法中訪問時起作用
@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();
}
}
當在不同的類中使用它時,它會拋出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.
}
我嘗試按照以下問題中提供的答案進行操作
Spring Boot - 環境 @Autowired 拋出 NullPointerException
我正在尋找解決問題的建議。
@Configuration
注釋在這里被誤用於InventoryStreamingConsumer
。 試試@Component
、 @Repository
或@Service
。
更新
另一個誤用是
StreamingConsumer streamingConsumer = factory.createStreamingConsumer(StreamType.valueOf(env.getRequiredProperty("streaming.application.type")));
@Autowired
或@Resource
只能在Spring
創建的bean
工作。 您的StreamingConsumerFactory factory
創建的streamingConsumer
不能使用@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
首先,請只用@SpringBootApplication
注釋主類
@SpringBootApplication
public class StreamingConsumerApplication {
}
@ComponentScan
如果您的包與主類不在同一結構內,主類在子包外部和父包內部,而所有其他類都在父包的同一或某個子包中,則需要@ComponentScan
。
其次,請創建一個 Configuration 類並單獨用@Configuration
對其進行注釋,並在那里為StreamingConsumer streamingConsumer
定義一個@Bean
,然后它可以被@Autowired
或注入InventoryStreamingConsumer
類中。
第三, @Bean
在哪里定義的? 你確定它可以為注射自動配置嗎
第四, InventoryStreamingConsumer
可以是一個@Component
,一旦上面的東西被排序,用@Autowiring
注入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.
}
我有類似的問題,但從不同的文件和不同的位置讀取屬性,如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");
}
}
嘗試添加
@PropertySource("classpath:application.properties")
在 InventoryStreamingConsumer 類上
這就是我如何使用它
@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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.