Статьи

Понимание Spring Web Initialization

Несколько лет назад большинство из нас использовали для написания конфигурационных XML-файлов везде, чтобы настроить даже простое приложение Java EE. Сегодня использование Java или Groovy для настройки проектов становится предпочтительным способом — вам просто нужно взглянуть на Gradle или функциональные возможности, представленные в последующих версиях Spring Framework, чтобы понять это.

Теперь я займусь настройкой контекста Spring для веб-приложения.

Java EE предоставляет интерфейс ServletContainerInitializer , который позволяет библиотекам получать уведомления о запуске веб-приложения. Начиная с Spring 3.1 у нас есть класс SpringServletContainerInitializer, который обрабатывает WebApplicationInitializer путем создания экземпляров всех найденных классов, реализующих этот интерфейс, сортируя их на основе аннотации @Order ( неаннотированные классы получают максимально возможный порядок, поэтому они обрабатываются в конце) и вызывая onStartup () метод.

Spring начиная с версии 3.2 предоставляет нам несколько классов, реализующих интерфейс WebApplicationInitializer , первым из которых является AbstractContextLoaderInitializer . Этот класс, включенный в модуль Spring -web, использует абстрактный метод createRootApplicationContext () для создания контекста приложения, делегируя его в ContextLoaderListener, который затем регистрируется в экземпляре ServletContext . Создание контекста приложения с использованием этого класса выглядит следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
public class SpringAnnotationWebInitializer
  extends AbstractContextLoaderInitializer {
 
  @Override
  protected WebApplicationContext createRootApplicationContext() {
    AnnotationConfigWebApplicationContext applicationContext =
      new AnnotationConfigWebApplicationContext();
    applicationContext.register(SpringAnnotationConfig.class);
    return applicationContext;
  }
 
}

Это был самый простой способ запустить веб-контекст Spring. Но если мы хотим воспользоваться преимуществами Spring MVC и не хотим вручную регистрировать DispatcherServlet , лучше использовать другой класс: AbstractDispatcherServletInitializer . Он расширяет предыдущий класс и добавляет два абстрактных метода: createServletApplicationContext () и getServletMappings () . Первый метод возвращает WebApplicationContext, который будет передан DispatcherServlet , который будет автоматически добавлен в контейнер ServletContext . Обратите внимание, что этот контекст будет установлен как дочерний по отношению к контексту, возвращенному методом createRootApplicationContext () . Второй метод — как вы, вероятно, уже вывели — возвращает отображения, которые используются при регистрации сервлета. Вы также можете переопределить метод getServletFilters (), если вам нужны какие-либо пользовательские фильтры, потому что реализация по умолчанию возвращает просто пустой массив. Примерная реализация с использованием этого класса может быть:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class SpringWebMvcInitializer
  extends AbstractDispatcherServletInitializer {
 
  @Override
  protected WebApplicationContext createRootApplicationContext() {
    AnnotationConfigWebApplicationContext applicationContext =
      new AnnotationConfigWebApplicationContext();
    applicationContext.register(SpringRootConfig.class);
    return applicationContext;
  }
 
  @Override
  protected WebApplicationContext createServletApplicationContext() {
    AnnotationConfigWebApplicationContext applicationContext =
      new AnnotationConfigWebApplicationContext();
    applicationContext.register(SpringMvcConfig.class);
    return applicationContext;
  }
 
  @Override
  protected String[] getServletMappings() {
    return new String[]{"/*"};
  }
 
}

И теперь последний, но не менее важный класс: AbstractAnnotationConfigDispatcherServletInitializer . Здесь мы видим дальнейший шаг в упрощении инициализации Spring — нам не нужно вручную создавать контексты, а просто устанавливать соответствующие классы конфигурации в методах getRootConfigClasses () и getServletConfigClasses () . Я надеюсь, что вы уже знакомы с этими именами, потому что они работают точно так же, как и в первом случае. Конечно, благодаря тому, что этот класс расширяет AbstractDispatcherServletInitializer, мы все равно можем переопределить getServletFilters () . Наконец, мы можем реализовать нашу конфигурацию следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
public class SpringWebMvcSimpleInitializer
  extends AbstractAnnotationConfigDispatcherServletInitializer {
 
  @Override
  protected Class<?>[] getRootConfigClasses() {
    return new Class[] {SpringRootConfig.class};
  }
 
  @Override
  protected Class<?>[] getServletConfigClasses() {
    return new Class[] {SpringMvcConfig.class};
  }
 
  @Override
  protected String[] getServletMappings() {
    return new String[]{"/*"};
  }
 
}

Ссылка: Понимание Spring Web Initialization от нашего партнера по JCG Якуба Кубрински в блоге Java (B) Log .