The Spring ApplicationContext – Spring ApplicationContext

最后修改: 2020年 7月 19日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll explore the Spring ApplicationContext interface in detail.

在本教程中,我们将详细探讨Spring的ApplicationContext接口。

2. The ApplicationContext Interface

2.ApplicationContext接口

One of the main features of the Spring framework is the IoC (Inversion of Control) container. The Spring IoC container is responsible for managing the objects of an application. It uses dependency injection to achieve inversion of control.

Spring框架的主要功能之一是IoC(反转控制)容器。Spring IoC容器负责管理应用程序的对象。它使用依赖性注入来实现控制的反转。

The interfaces BeanFactory and ApplicationContext represent the Spring IoC container. Here, BeanFactory is the root interface for accessing the Spring container. It provides basic functionalities for managing beans.

接口BeanFactoryApplicationContext代表Spring IoC容器。这里,BeanFactory是访问Spring容器的根接口。它提供了管理Bean的基本功能。

On the other hand, the ApplicationContext is a sub-interface of the BeanFactory. Therefore, it offers all the functionalities of BeanFactory.

另一方面,ApplicationContextBeanFactory的一个子接口。因此,它提供了BeanFactory的所有功能。

Furthermore, it provides more enterprise-specific functionalities. The important features of ApplicationContext are resolving messages, supporting internationalization, publishing events, and application-layer specific contexts. This is why we use it as the default Spring container.

此外,它还提供了更多的企业特定功能ApplicationContext的重要功能是解析消息、支持国际化、发布事件和应用层特定上下文。这就是为什么我们使用它作为默认的Spring容器。

3. What Is a Spring Bean?

3.什么是Spring Bean?

Before we dive deeper into the ApplicationContext container, it’s important to know about Spring beans. In Spring, a bean is an object that the Spring container instantiates, assembles, and manages.

在我们深入了解ApplicationContext容器之前,有必要了解一下Spring Bean。在Spring中,beanSpring容器实例化、组装和管理的一个对象

So should we configure all of the objects of our application as Spring beans? Well, as a best practice, we shouldn’t.

那么,我们是否应该把我们应用程序的所有对象都配置成Spring Bean呢?嗯,作为一个最佳实践,我们不应该。

As per Spring documentation in general, we should define beans for service layer objects, data access objects (DAOs), presentation objects, infrastructure objects such as Hibernate SessionFactories, JMS Queues, and so forth.

根据Spring文档,一般来说,我们应该为服务层对象、数据访问对象(DAO)、演示对象、基础设施对象(如Hibernate SessionFactories, JMS Queues)等定义bean。

Also, typically, we shouldn’t configure fine-grained domain objects in the container. It’s usually the responsibility of DAOs and business logic to create and load domain objects.

另外,通常情况下,我们不应该在容器中配置细粒度的域对象。创建和加载域对象通常是DAO和业务逻辑的责任。

Now let’s define a simple Java class that we’ll use as a Spring bean in this tutorial:

现在让我们定义一个简单的Java类,在本教程中我们将把它作为一个Spring Bean。

public class AccountService {

  @Autowired
  private AccountRepository accountRepository;

  // getters and setters
}

4. Configuring Beans in the Container

4.在容器中配置Bean

As we know, the primary job of the ApplicationContext is to manage beans.

正如我们所知,ApplicationContext的主要工作是管理Bean。

As such, an application must provide the bean configuration to the ApplicationContext container. A Spring bean configuration consists of one or more bean definitions. In addition, Spring supports different ways of configuring beans.

因此,应用程序必须向ApplicationContext容器提供bean配置。一个Spring的Bean配置由一个或多个Bean定义组成。此外,Spring支持配置Bean的不同方式。

4.1. Java-Based Configuration

4.1.基于Java的配置

First, we’ll start with Java-based configuration as it’s the newest and most preferred way of bean configuration. It’s available from Spring 3.0 onward.

首先,我们将从基于Java的配置开始,因为它是最新的、最受欢迎的bean配置方式。它从Spring 3.0开始可用。

Java configuration typically uses @Bean-annotated methods within a @Configuration class. The @Bean annotation on a method indicates that the method creates a Spring bean. Moreover, a class annotated with @Configuration indicates that it contains Spring bean configurations.

Java配置通常在@Configuration类中使用@Bean标注的方法。方法上的@Bean注解表明该方法创建了一个Spring Bean。此外,被@Configuration注解的类表明它包含Spring Bean的配置。

Now let’s create a configuration class to define our AccountService class as a Spring bean:

现在让我们创建一个配置类,将我们的AccountService类定义为一个Spring Bean。

@Configuration
public class AccountConfig {

  @Bean
  public AccountService accountService() {
    return new AccountService(accountRepository());
  }

  @Bean
  public AccountRepository accountRepository() {
    return new AccountRepository();
  }
}

4.2. Annotation-Based Configuration

4.2.基于注释的配置

Spring 2.5 introduced annotation-based configuration as the first step to enable bean configurations in Java.

Spring 2.5引入了基于注解的配置,作为在Java中实现Bean配置的第一步。

In this approach, we first enable annotation-based configuration via XML configuration. Then we use a set of annotations on our Java classes, methods, constructors, or fields to configure beans. Some examples of these annotations are @Component, @Controller, @Service, @Repository, @Autowired, and @Qualifier.

在这种方法中,我们首先通过XML配置启用基于注解的配置。然后我们在我们的Java类、方法、构造函数或字段上使用一组注解来配置Bean。这些注解的一些例子有:@Component, @Controller, @Service, @Repository, @Autowired, 和@Qualifier

Notably, we use these annotations with Java-based configuration as well. Also worth mentioning, Spring keeps on adding more capabilities to these annotations with each release.

值得注意的是,我们也在基于Java的配置中使用这些注解。另外值得一提的是,Spring在每个版本中都会不断为这些注解添加更多的功能。

Now let’s see a simple example of this configuration.

现在让我们看看这个配置的一个简单例子。

First, we’ll create the XML configuration, user-bean-config.xml, to enable annotations:

首先,我们将创建XML配置,user-bean-config.xml,以启用注释。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
  
  <context:annotation-config/>
  <context:component-scan base-package="com.baeldung.applicationcontext"/>

</beans>

Here, the annotation-config tag enables annotation-based mappings. The component-scan tag also tells Spring where to look for annotated classes.

这里,annotation-config标签启用了基于注释的映射component-scan标签还告诉Spring在哪里寻找注解类。

Second, we’ll create the UserService class and define it as a Spring bean using the @Component annotation:

其次,我们将创建UserService类,并使用@Component注解将其定义为一个Spring Bean。

@Component
public class UserService {
  // user service code
}

Then we’ll write a simple test case to test this configuration:

然后我们将写一个简单的测试案例来测试这个配置。

ApplicationContext context = new ClassPathXmlApplicationContext("applicationcontext/user-bean-config.xml");
UserService userService = context.getBean(UserService.class);
assertNotNull(userService);

4.3. XML-Based Configuration

4.3.基于XML的配置

Finally, let’s take a look at XML-based configuration. This is the traditional way of configuring beans in Spring.

最后,让我们看一下基于XML的配置。这是在Spring中配置Bean的传统方式。

Obviously, in this approach, we do all bean mappings in an XML configuration file.

显然,在这种方法中,我们在一个XML配置文件中做所有的bean映射

So let’s create an XML configuration file, account-bean-config.xml, and define beans for our AccountService class:

因此,让我们创建一个XML配置文件,account-bean-config.xml,并为我们的AccountService类定义bean。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd">
	  
  <bean id="accountService" class="com.baeldung.applicationcontext.AccountService">
    <constructor-arg name="accountRepository" ref="accountRepository" />
  </bean>
	
  <bean id="accountRepository" class="com.baeldung.applicationcontext.AccountRepository" />
</beans>

5. Types of ApplicationContext

5.ApplicationContext的类型

Spring provides different types of ApplicationContext containers suitable for different requirements. These are implementations of the ApplicationContext interface. So let’s take a look at some of the common types of ApplicationContext.

Spring提供了不同类型的ApplicationContext容器,适合不同的需求。这些都是ApplicationContext接口的实现。因此,让我们来看看一些常见的ApplicationContext的类型。

5.1. AnnotationConfigApplicationContext

5.1.AnnotationConfigApplicationContext

First, let’s see the AnnotationConfigApplicationContext class, which was introduced in Spring 3.0. It can take classes annotated with @Configuration, @Component, and JSR-330 metadata as input.

首先,让我们看看AnnotationConfigApplicationContext 类,它是在Spring 3.0中引入的。它可以接受以@Configuration@Component和JSR-330元数据注释的类作为输入。

So let’s see a simple example of using the AnnotationConfigApplicationContext container with our Java-based configuration:

因此,让我们看看使用AnnotationConfigApplicationContext容器和基于Java的配置的一个简单例子。

ApplicationContext context = new AnnotationConfigApplicationContext(AccountConfig.class);
AccountService accountService = context.getBean(AccountService.class);

5.2. AnnotationConfigWebApplicationContext

5.2.AnnotationConfigWebApplicationContext

AnnotationConfigWebApplicationContext is a web-based variant of AnnotationConfigApplicationContext.

AnnotationConfigWebApplicationContext AnnotationConfigApplicationContext的一个基于Web的变体

We may use this class when we configure Spring’s ContextLoaderListener servlet listener or a Spring MVC DispatcherServlet in a web.xml file.

当我们在web.xml文件中配置Spring的ContextLoaderListener servlet监听器或Spring MVC的DispatcherServlet时,我们可以使用这个类。

Moreover, from Spring 3.0 onward, we can also configure this application context container programmatically. All we need to do is implement the WebApplicationInitializer interface:

此外,从Spring 3.0开始,我们也可以以编程方式配置这个应用上下文容器。我们所需要做的就是实现WebApplicationInitializer接口。

public class MyWebApplicationInitializer implements WebApplicationInitializer {

  public void onStartup(ServletContext container) throws ServletException {
    AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
    context.register(AccountConfig.class);
    context.setServletContext(container);

    // servlet configuration
  }
}

5.3. XmlWebApplicationContext

5.3.XmlWebApplicationContext

If we use the XML based configuration in a web application, we can use the XmlWebApplicationContext class.

如果我们在一个Web应用中使用基于XML的配置,我们可以使用XmlWebApplicationContext类。

As a matter of fact, configuring this container is like the AnnotationConfigWebApplicationContext class only, which means we can configure it in web.xml, or implement the WebApplicationInitializer interface:

事实上,配置这个容器就像AnnotationConfigWebApplicationContext类一样,这意味着我们可以在web.xml中配置它,或者实现WebApplicationInitializer接口。

public class MyXmlWebApplicationInitializer implements WebApplicationInitializer {

  public void onStartup(ServletContext container) throws ServletException {
    XmlWebApplicationContext context = new XmlWebApplicationContext();
    context.setConfigLocation("/WEB-INF/spring/applicationContext.xml");
    context.setServletContext(container);

    // Servlet configuration
  }
}

5.4. FileSystemXMLApplicationContext

5.4.FileSystemXMLApplicationContext

We use the FileSystemXMLApplicationContext class to load an XML-based Spring configuration file from the file system or from URLs. This class is useful when we need to load the ApplicationContext programmatically. In general, test harnesses and standalone applications are some of the possible use cases for this.

我们使用FileSystemXMLApplicationContext 类来从文件系统或从URL加载基于XML的Spring配置文件。当我们需要以编程方式加载ApplicationContext时,这个类很有用。一般来说,测试线束和独立的应用程序是其中一些可能的用例。

For example, let’s see how we can create this Spring container and load the beans for our XML-based configuration:

例如,让我们看看如何创建这个Spring容器并为我们基于XML的配置加载bean。

String path = "C:/myProject/src/main/resources/applicationcontext/account-bean-config.xml";

ApplicationContext context = new FileSystemXmlApplicationContext(path);
AccountService accountService = context.getBean("accountService", AccountService.class);

5.5. ClassPathXmlApplicationContext

5.5.ClassPathXmlApplicationContext

In case we want to load an XML configuration file from the classpath, we can use the ClassPathXmlApplicationContext class. Similar to FileSystemXMLApplicationContext, it’s useful for test harnesses, as well as application contexts embedded within JARs.

如果我们想从classpath加载一个XML配置文件,我们可以使用ClassPathXmlApplicationContext类。与FileSystemXMLApplicationContext类似,它对测试线束以及嵌入JAR中的应用程序上下文非常有用。

So let’s see an example of using this class:

因此,让我们看一个使用这个类的例子。

ApplicationContext context = new ClassPathXmlApplicationContext("applicationcontext/account-bean-config.xml");
AccountService accountService = context.getBean("accountService", AccountService.class);

6. Additional Features of ApplicationContext

6.ApplicationContext的附加功能

6.1. Message Resolution

6.1.信息决议

The ApplicationContext interface supports message resolution and internationalization by extending the MessageSource interface. Furthermore, Spring provides two MessageSource implementations, ResourceBundleMessageSource and StaticMessageSource.

ApplicationContext接口支持消息解析和国际化通过扩展MessageSource接口。此外,Spring提供了两个MessageSource实现,ResourceBundleMessageSource StaticMessageSource

We can use the StaticMessageSource to programmatically add messages to the source; however, it supports basic internationalization and is more suitable for tests than production use.

我们可以使用StaticMessageSource以编程方式将消息添加到源中;但是,它支持基本的国际化,更适合于测试而非生产使用。

On the other hand, ResourceBundleMessageSource is the most common implementation of MessageSource. It relies on the underlying JDK’s ResouceBundle implementation. It also uses the JDK’s standard message parsing provided by MessageFormat.

另一方面,ResourceBundleMessageSourceMessageSource的最常见实现。它依赖于底层 JDK 的 ResouceBundle 实现。它还使用由MessageFormat提供的JDK的标准消息解析。

Now let’s see how can we use the MessageSource to read the messages from a properties file.

现在让我们看看如何使用MessageSource来读取属性文件中的信息。

First, we’ll create the messages.properties file on the classpath:

首先,我们将在classpath上创建messages.properties文件。

account.name=TestAccount

Second, we’ll add a bean definition in our AccountConfig class:

其次,我们将在我们的AccountConfig类中添加一个bean定义。

@Bean
public MessageSource messageSource() {
  ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
  messageSource.setBasename("config/messages");
  return messageSource;
}

Third, we’ll inject the MessageSource in the AccountService:

第三,我们将在AccountService中注入MessageSource

@Autowired
private MessageSource messageSource;

Finally, we can use the getMessage method anywhere in the AccountService to read the message:

最后,我们可以在AccountService的任何地方使用getMessage方法来读取消息。

messageSource.getMessage("account.name", null, Locale.ENGLISH);

Spring also provides the ReloadableResourceBundleMessageSource class, which allows for reading files from any Spring resource location, and supports hot reloading of bundle property files.

Spring还提供了ReloadableResourceBundleMessageSource 类,它允许从任何Spring资源位置读取文件,并支持捆绑属性文件的热重新加载。

6.2. Event Handling

6.2. 事件处理

ApplicationContext supports event handling with the help of the ApplicationEvent class and the ApplicationListener interface. It supports built-in events like ContextStartedEvent, ContextStoppedEvent, ContextClosedEvent, and RequestHandledEvent. Moreover, it also supports custom events for business use cases.

ApplicationContextApplicationEvent类和ApplicationListener接口的帮助下支持事件处理。它支持内置事件,如ContextStartedEventContextStoppedEventContextClosedEventRequestHandledEvent。此外,它还支持自定义事件,以满足商业用例的需要。

7. Conclusion

7.结语

In this article, we discussed various aspects of the ApplicationContext container in Spring. We also explored different examples of how to configure Spring beans in an AppicationContext. Finally, we learned how to create and use different types of ApplicationContext.

在这篇文章中,我们讨论了Spring中ApplicationContext容器的各个方面。我们还探讨了如何在AppicationContext中配置Spring Bean的不同例子。最后,我们学习了如何创建和使用不同类型的ApplicationContext

As always, the complete code is available over on GitHub.

一如既往,完整的代码可在GitHub上获得