Spring中ApplicationContext是否自动实例化?Spring Boot上下文如何自动装配?
Let's break down your questions one by one, since there are a few key points here:
1. Will ApplicationContext be instantiated automatically in plain Spring?
Short answer: No. In core Spring (without Spring Boot), Spring won't magically create the ApplicationContext for you. Annotations like @Component (to mark beans) and @ComponentScan (to tell Spring where to look for beans) just define the rules—but they don't trigger the context initialization process. You have to kick that off manually.
2. Your attempted approach: Creating context inside AppConfig
The code you wrote where you instantiate AnnotationConfigApplicationContext directly inside your AppConfig class is a bad idea—here's why:
AppConfigitself is a Spring-managed bean (thanks to@Configuration). When Spring tries to create an instance ofAppConfig, it will execute that code and create a new context... which will then try to create anotherAppConfig, and so on. You'll end up with an infinite loop of context creation.- Every time
AppConfigis instantiated, you get a brand new context. That's extremely inefficient and will lead to duplicate beans and memory issues.
3. Recommended way to instantiate ApplicationContext in plain Spring
You should initialize the context in a separate entry point class—usually a main method that acts as your application's bootstrap. Here's the correct pattern:
// Your existing config class (unchanged) @Configuration @ComponentScan public class AppConfig { } // Your component class (unchanged) @Component public class Car { } // The bootstrap class where you start the context public class MainApp { public static void main(String[] args) { // Initialize the context once, using your config ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); // Now you can fetch beans from the context Car myCar = context.getBean(Car.class); // Use your bean as needed System.out.println("Got car bean: " + myCar); } }
This way, you create the context exactly once when your application starts, and all beans are loaded into that single context.
4. How to make the context available across your project?
In most cases, you shouldn't need to pass the context around manually. If your classes are Spring-managed (marked with @Component, @Service, @Repository, etc.), you can use dependency injection to get the beans you need, instead of fetching them from the context directly.
For example:
@Service public class CarService { // Spring will automatically inject the Car bean here @Autowired private Car car; public void doSomething() { // Use the injected Car bean System.out.println("Using car: " + car); } }
If you truly need access to the context itself (for advanced use cases like dynamic bean lookup), you can implement ApplicationContextAware or simply inject it:
@Component public class ContextUser implements ApplicationContextAware { private ApplicationContext context; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.context = applicationContext; } // Or just use @Autowired directly // @Autowired // private ApplicationContext context; }
5. How does Spring Boot handle context initialization?
Spring Boot simplifies this entire process by handling the bootstrap automatically. Here's what happens under the hood when you run a Spring Boot app:
- The
@SpringBootApplicationannotation combines@Configuration,@ComponentScan, and@EnableAutoConfiguration—so it defines the config, enables bean scanning, and loads auto-configured beans (like embedded servers, data sources, etc.). - When you call
SpringApplication.run(YourMainClass.class, args)in your main method, Spring Boot:- Creates the appropriate
ApplicationContextimplementation (e.g.,AnnotationConfigServletWebServerApplicationContextfor web apps). - Scans for beans starting from your main class's package and subpackages.
- Loads all auto-configuration beans.
- Registers the
ApplicationContextitself as a bean in the context, so you can@Autowiredit anywhere in your Spring-managed beans.
- Creates the appropriate
A typical Spring Boot setup looks like this:
@SpringBootApplication public class CarApp { public static void main(String[] args) { // Spring Boot initializes the context and returns it ApplicationContext context = SpringApplication.run(CarApp.class, args); // Optional: Fetch beans directly here (but prefer DI in business code) Car car = context.getBean(Car.class); } } // In a service class, you can inject beans or the context easily @Service public class CarService { @Autowired private Car car; @Autowired private ApplicationContext context; // Works out of the box! }
Key Takeaways
- Plain Spring: You must manually initialize the
ApplicationContextin a bootstrap class—never inside a config bean. Use dependency injection instead of fetching beans directly from the context whenever possible. - Spring Boot: The framework handles context initialization for you via
SpringApplication.run(), and the context is available for injection with@Autowired.
内容的提问来源于stack exchange,提问作者Stefano Sambruna

