web.xml срещу Initializer с Spring

1. Общ преглед

В тази статия ще разгледаме три различни подхода за конфигуриране на DispatcherServlet, налични в последните версии на Spring Framework:

  1. Ще започнем с XML конфигурация и файл web.xml
  2. След това ще мигрираме декларацията на Servlet от файла web.xml в Java config, но ще оставим всяка друга конфигурация в XML
  3. И накрая, в третата и последна стъпка от рефакторинга, ще имаме 100% конфигуриран от Java проект

2. DispatcherServlet

Една от основните концепции на Spring MVC е DispatcherServlet . Пролетната документация го определя като:

Централен диспечер за манипулатори / контролери на HTTP заявки, например за уеб потребителски контролери или износители на отдалечени услуги, базирани на HTTP. Изпращания към регистрирани манипулатори за обработка на уеб заявка, осигуряващи удобни съоръжения за картографиране и обработка на изключения.

По принцип DispatcherServlet е входната точка на всяко приложение на Spring MVC . Целта му е да прихваща HTTP заявки и да ги изпраща към правилния компонент, който ще знае как да се справи с него.

3. Конфигуриране с w eb.xml

Ако се занимавате с наследени пролетни проекти, много често се среща XML конфигурация и до Spring 3.1 единственият начин за конфигуриране на DispatcherServlet е бил с файла WEB-INF / web.xml . В този случай са необходими две стъпки.

Да видим примерна конфигурация - първата стъпка е декларацията на Servlet:

 dispatcher  org.springframework.web.servlet.DispatcherServlet   contextConfigLocation /WEB-INF/spring/dispatcher-config.xml  1 

С този блок на XML декларираме сървлет, който:

  1. Нарича се „ диспечер
  2. Е екземпляр на org.springframework.web.servlet.DispatcherServlet
  3. Ще бъде инициализиран с параметър, наречен contextConfigLocation, който съдържа пътя към конфигурационния XML

load-on-startup е целочислена стойност, която определя реда за зареждане на множество сървлети. Така че, ако трябва да декларирате повече от един сървлет, можете да определите в кой ред те ще бъдат инициализирани. Сервлетите, маркирани с по-ниски цели числа, се зареждат преди сървлетите, маркирани с по-високи цели числа.

Сега нашият сървлет е конфигуриран. Втората стъпка е деклариране на сървлет-mapping :

 dispatcher / 

С картографирането на сървлета ние го ограничаваме от името му до URL шаблон, който определя какви HTTP заявки ще бъдат обработвани от него.

4. Хибридна конфигурация

С приемането на версията 3.0 на API на Servlet , файлът web.xml стана незадължителен и вече можем да използваме Java за конфигуриране на DispatcherServlet .

Можем да регистрираме сървлет, изпълняващ WebApplicationInitializer . Това е еквивалентът на XML конфигурацията по-горе:

public class MyWebAppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext container) { XmlWebApplicationContext context = new XmlWebApplicationContext(); context.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml"); ServletRegistration.Dynamic dispatcher = container .addServlet("dispatcher", new DispatcherServlet(context)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/"); } }

В този пример ние сме:

  1. Внедряване на интерфейса WebApplicationInitializer
  2. Замяната на onStartup метод ние създаваме нова XmlWebApplicationContext конфигуриран с един и същи файл, подадена като contextConfigLocation да сървлета в XML примера
  3. След това създаваме екземпляр на DispatcherServlet с новия контекст, който току-що създадохме
  4. И накрая регистрираме сървлета с модел на URL на съпоставяне

Затова използвахме Java, за да декларираме сървлета и да го обвържем с картографиране на URL, но запазихме конфигурацията в отделен XML файл: depecher-config.xml .

5. 100% Java конфигурация

С този подход нашият сървлет е деклариран в Java , но все още се нуждаем от XML файл, за да го конфигурираме. С WebApplicationInitializer можете да постигнете 100% Java конфигурация.

Нека да видим как можем да рефакторираме предишния пример.

Първото нещо, което ще трябва да направим, е да създадем контекста на приложението за сървлета.

Този път ще използваме контекст, базиран на пояснения, за да можем да използваме Java и пояснения за конфигуриране и да премахнем необходимостта от XML файлове като depecher-config.xml :

AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();

След това този тип контекст може да бъде конфигуриран, като регистрира конфигурационен клас:

context.register(AppConfig.class);

Или задаване на цял пакет, който ще бъде сканиран за конфигурационни класове:

context.setConfigLocation("com.example.app.config");

Сега, когато контекстът на нашето приложение е създаден, можем да добавим слушател към ServletContext, който ще зареди контекста:

container.addListener(new ContextLoaderListener(context));

Следващата стъпка е създаването и регистрирането на нашия диспечерски сървлет:

ServletRegistration.Dynamic dispatcher = container .addServlet("dispatcher", new DispatcherServlet(context)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/");

Сега нашият WebApplicationInitializer трябва да изглежда така:

public class MyWebAppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext container) { AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); context.setConfigLocation("com.example.app.config"); container.addListener(new ContextLoaderListener(context)); ServletRegistration.Dynamic dispatcher = container .addServlet("dispatcher", new DispatcherServlet(context)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/"); } }

Java and annotation configuration offers many advantages. Usually it leads to shorter and more concise configuration and annotations provide more context to declarations, as it's co-located with the code that they configure.

But this is not always a preferable or even possible way. For example some developers may prefer keeping their code and configuration separated, or you may need to work with third party code that you can't modify.

6. Conclusion

In this article we covered different ways to configure a DispatcherServlet in Spring 3.2+ and it's up to you to decide which one to use based on your preferences. Spring will accommodate to your decision whatever you choose.

You can find the source code from this article on Github here and here.