Я обнаружил, что многие разработчики 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; @Configuration public 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 .