4

Target.java:

package me;

@Component
public class Target implements Runnable {   
    @Autowired
    private Properties properties;

    public Target(){
        properties.getProperty('my.property');
    }

    public void run() {
        //do stuff
    }
}

Config.java:

@Configuration
@ComponentScan(basePackages = {"me"})
public class Config {
    @Bean(name="properties")
    public PropertiesFactoryBean properties() {
        PropertiesFactoryBean bean = new PropertiesFactoryBean();
        bean.setLocation(new FileSystemResource("src/my.properties"));
        return bean;
    }

    public static void main(String[] argv) throws Exception {
        ApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
        Target t = context.getBean(Target.class);
        t.run();
    }
}

With the above code. Bottom of stack:

Caused by: java.lang.NullPointerException
 at me.Target.<init>(Target.java:9)
 ....
3
  • src/ can not be resolved, use classpath:my.properties instead. Commented Apr 5, 2016 at 6:30
  • That's not the issue. Commented Apr 5, 2016 at 6:32
  • when i walk through with the debugger the bean is successfully returned and I can query the property file when inside Config. The properties file is seen fine. Commented Apr 5, 2016 at 6:39

2 Answers 2

3

You are doing field injection. You're referencing "to-be-autowired" instance variable inside constructor. In constructor, properties field is null because it has not been autowired yet. You can use constructor injection.

package me;

@Component
public class Target implements Runnable {   
    private final Properties properties;

    @Autowired
    public Target(Properties properties){
        this.properties = properties;
        properties.getProperty('my.property');
    }

    public void run() {
        //do stuff
    }
}
Sign up to request clarification or add additional context in comments.

Comments

2

The constructor is called before properties is set. You are calling a method on properties in constructor before spring gets to set it. Use something like PostConstruct:

package me;

@Component
public class Target implements Runnable {   
    @Autowired
    private Properties properties;

    public Target(){}

    @PostConstruct
    public void init() {
        properties.getProperty('my.property');
    }

    public void run() {
      //do stuff
   }

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.