Note: I'm updating this since I've found a solution.
This question is similar to Why is my Spring @Autowired field null?, but I'm using the main()
method here. The solution is to mark Foo
with @Component
and autowire it into Main
through a @PostConstruct
method. I learned about this through How to use autowired (@Autowired) references from main(String[] args) method?
On PostContruct: Why use @PostConstruct?
@PostConstruct
makes sure all beans are fully initialized before executing (including the bean class you're actively editing).
But the bigger issue was me doing Foo foo = new Foo()
. foo
is outside the scope of Spring's context and 100% of it's lifecycle is managed by me. Put everything back in Spring's hands by autowiring everything:
New Main.java
package org.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javax.annotation.PostConstruct;
@SpringBootApplication
public class Main {
@Autowired
Foo foo;
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
@PostConstruct
public void test() {
foo.message();
}
}
New Foo.java
package org.example;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
@Component
@Slf4j
public class Foo {
@Autowired
Bar bar;
public Foo() {
log.info("Foo bean created");
}
public void message() {
log.info(bar.getWord());
}
}
The original question is below:
I've followed so many Spring tutorials that do it this way, and it never works on my end. No clue what I'm doing wrong, but I seriously need help figuring this out.
Main.java
package org.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
Foo foo = new Foo();
foo.message();
}
}
Foo.java
package org.example;
import org.springframework.beans.factory.annotation.Autowired;
public class Foo {
@Autowired
Bar bar;
public void message() {
System.out.println(bar.getWord());
}
}
Bar.java
package org.example;
import org.springframework.stereotype.Component;
@Component
public class Bar {
String word = "word";
public String getWord() {return word;}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>untitled</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.7.5</version>
</dependency>
</dependencies>
</project>
When running from Main(), I get:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "org.example.Bar.getWord()" because "this.bar" is null
at org.example.Foo.message(Foo.java:11)
at org.example.Main.main(Main.java:14)
These are all in the same directory/package. I've been at this for two hours and have no clue why this isn't working. Any help on this would be greatly appreciated.
What I tried:
- Using @Autowired to create a bean that I can use in another class.
What I expected to happen:
- The String
word
to be printed to the console. - My understanding is that a class that has @Component is up for grabs by Spring to be a bean if you're using @Autowired to inject it. I have met that criteria and I am not getting my expected result.
What actually resulted:
- A NullPointerException