I'm a total beginner with Spring. I'm currently trying to just run a very simple project just to start learning about Spring and understanding IoC and dependency injection. At first I created a simple Spring Boot project and it worked, but now I'm trying to do it without boot because I want to understand better what's going on. I don't understand how to do this (full class below):
SpringApplication.run(TestSpringApplication.class, args);
I tried to do this:
TestSpringApplication app = new TestSpringApplication();
app.run(args);
But then inside the run() method, the @Autowired messageRepository is null. I'm guessing this is because I created my TestSpringApplication using new instead of applicationContext.getBean()? But how can I access/get the applicationContext in my static main method?
Forgive me if it might sound trivial, I'm starting from almost zero here and I have a very hard time finding easy tutorials.
Here is what I'm trying to do but is not working:
package com.cypherf;
import com.cypherf.model.Message;
import com.cypherf.repository.MessageRepository;
import com.cypherf.service.MessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
public class TestSpringApplication {
@Autowired
private ApplicationContext context;
@Autowired
private MessageRepository messageRepository;
@Autowired
private MessageService messageService;
public static void main(String[] args) {
TestSpringApplication app = new TestSpringApplication();
app.run(args);
}
public void run(String... args) {
messageRepository.save(new Message("Message one"));
messageRepository.save(new Message("Message two"));
messageRepository.save(new Message("Message two"));
messageService.printAllMessages();
}
}
Here is my previous class with Spring Boot which is working:
package com.cypherf;
import com.cypherf.model.Message;
import com.cypherf.repository.MessageRepository;
import com.cypherf.service.MessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class TestSpringApplication implements CommandLineRunner {
@Autowired
private MessageRepository messageRepository;
@Autowired
private MessageService messageService;
public static void main(String[] args) {
SpringApplication.run(TestSpringApplication.class, args);
}
public void run(String... args) throws Exception {
messageRepository.save(new Message("Message one"));
messageRepository.save(new Message("Message two"));
messageRepository.save(new Message("Message two"));
messageService.printAllMessages();
}
}
If you're not using Spring Boot, then you have to set up the Spring container by yourself by creating an ApplicationContext
bean.
One way of doing so is by using the AnnotationConfigApplicationContext
class. For example:
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(TestSpringApplication.class);
MessageService messageService = context.getBean(MessageService.class);
messageService.printAllMessages();
}
But this only creates a basic application context for you. Without Spring Boot, you no longer have access to autoconfigurations. This means that:
DataSource
bean.EntityManagerFactory
bean and a TransactionManager
(and you have to configure Spring Data JPA as well).printAllMessages()
relies on a logging framework, you now have to configure that one by yourself as well.In addition, classes like CommandLineRunner
are also no longer available. Now you have to rely on alternatives such as listening to the ContextRefreshedEvent
.