Я обнаружил, что многие разработчики Spring, которых я знаю, до сих пор не знают или не используют Spring Java Configuration (или JavaConfig). Spring 3.0 представил эту функцию, которая позволяет полностью настраивать Spring на Java — не нужно больше XML! Мне действительно нравится использовать JavaConfig, потому что, ну … это Java! Это означает, что он обладает всеми преимуществами безопасности типов Java и поддержки IDE:
- Опечатки генерируют ошибку компиляции — больше не нужно ждать времени загрузки, чтобы найти опечатки XML
- Инструменты рефакторинга IDE автоматически обновят JavaConfig, потому что это обычная Java
- Функция автоматического импорта IDE может использоваться вместо ввода полностью определенных имен классов в XML
- Функция детализации IDE
- Функция автозаполнения IDE
- Я думаю, вы понимаете, все, что работает с Java ..
Некоторые из вышеперечисленных функций встроены в более продвинутые IDE с поддержкой Spring, но просто приятно не полагаться на пользовательскую поддержку IDE Spring для получения этих функций. Проверка во время компиляции очень важна для меня. Я часто выполняю рефакторинг своего кода, и изменение имен полей или перемещение или переименование файла Java часто нарушают мою конфигурацию XML Spring. Конечно, я обычно не осознаю этого, пока не разверну приложение и не получу ошибку инициализации Spring. Теперь моя среда IDE автоматически обновляет ссылки JavaConfig, когда я выполняю рефакторинг своего кода, потому что это просто обычная java. Кроме того, если я забуду использовать инструменты рефакторинга моей IDE, я все равно получаю ошибку компиляции в JavaConfig, которая предупреждает меня перед развертыванием, что у меня есть проблема.
Позвольте мне показать базовый пример того, как конфигурация XML переводится в JavaConfig. Во-первых, конфигурация XML:
|
1
2
3
4
5
6
7
8
9
|
<beans> <bean id="PersonService" class="com.codetutr.PersonService"> <constructor-arg ref="personDao" /> </bean> <bean id="personDao" class="com.codetutr.dao.PersonDao"> <property name="endpoint" value="localhost" /> </bean></beans> |
Переведено в JavaConfig:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package com.codetutr.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import com.codetutr.dao.PersonDao;import com.codetutr.service.PersonService;@Configurationpublic class AppConfig { @Bean public PersonService personService() { return new PersonService(personDao()); } @Bean public PersonDao personDao() { PersonDao personDao = new PersonDao(); personDao.setEndpoint("localhost"); return personDao; }} |
Это довольно простое преобразование один в один. Каждый документ <beans> переводится в класс Java с аннотацией @Configuration . Каждый элемент <bean> переводится в один метод, аннотированный @Bean . Название метода соответствует идентификатору компонента. Чтобы ссылаться на другой компонент в JavaConfig, вы просто вызываете метод для требуемого компонента (см. personService выше).
Еще одно наблюдение, которое я имел в отношении Spring JavaConfig, заключается в том, что более естественным является использование конструктора по сравнению с установщиком — потому что это приводит к однострочному методу. Для меня это плюс, так как я обычно предпочитаю инъекцию в конструктор. Если класс требует определенных зависимостей для правильного функционирования, я предпочитаю требовать их в конструкторе. Таким образом, я могу гарантировать, что класс инициализирован в допустимое состояние. Я заметил, что по какой-то причине внедрение конструктора, кажется, редко используется в конфигурации XML. Может, constructor-arg слишком сложен для запоминания? Я не знаю, но мне нравится, что JavaConfig, кажется, возвращает это назад.
Теперь, чтобы загрузить контекст приложения JavaConfig, Spring предоставил новую реализацию ApplicationContext: AnnotationConfigApplicationContext . Он используется так же, как мы привыкли использовать ClassPathXmlApplicationContext :
|
1
2
|
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);PersonService personService = ctx.getBean(PersonService.class); |
Или, если вы находитесь в веб-приложении:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
<servlet> <servlet-name>myServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextClass</param-name> <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value> </init-param> <init-param> <param-name>contextConfigLocation</param-name> <param-value>com.codetutr.config.AppConfig</param-value> </init-param> <load-on-startup>1</load-on-startup></servlet> |
Обратите внимание, что имя пакета или имя класса может быть передано для параметра contextConfigLocation выше.
Или, наконец, если вы используете конфигурацию Java Servlet 3:
|
01
02
03
04
05
06
07
08
09
10
11
|
public class SpringWebAppInitializer implements WebApplicationInitializer { @Override public void onStartup(final ServletContext servletContext) throws ServletException { final AnnotationConfigWebApplicationContext springContext = new AnnotationConfigWebApplicationContext(); springContext.register(AppConfig.class); final ServletRegistration.Dynamic springServlet = servletContext.addServlet("myServlet", new DispatcherServlet(springContext)); springServlet.setLoadOnStartup(1); springServlet.addMapping("/*"); }} |
Этот пост только коснулся поверхности JavaConfig. Я расскажу о том, как импортировать bean-компоненты из других классов @Configuration или XML-файлов, а также как использовать пользовательские пространства имен. Также ознакомьтесь с моим постом о том, как настроить приложение Spring-MVC с помощью JavaConfig .