Помните времена, когда нам приходилось регистрировать диспетчеров, viewResolvers и т. Д., Чтобы сделать наше весеннее веб-приложение? Тогда была @EnableWebMvc
аннотация, и теперь даже это излишне.
В настоящее время единственное, что вам нужно сделать, это добавить org.springframework.boot:spring-boot-starter-web
зависимость к вашему проекту, а все остальное делается автоматически.
То же самое касается подключения к базе данных. Не так давно минимальная конфигурация Spring-контекста с учетом БД была:
- Зарегистрировать источник данных (
<jdbc:embedded-database id="dataSource" type="HSQL"/>
) - Регистрация менеджера сущностей (через фабрику менеджеров сущностей) (
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
) - Зарегистрировать менеджер транзакций (
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" >
) - Возврат по границам транзакций на основе аннотаций (
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="false"/>
)
По ходу дела мы отбросили конфиги XML в пользу конфигураций. Теперь все, что вам нужно сделать, это добавить еще одну зависимость org.springframework.boot:spring-boot-starter-data-jpa
и некоторый драйвер БД (например com.h2database:h2
) и — опять же, Spring создает все за кулисами.
Я не знаю о вас, но я становлюсь подозрительным, когда так много вещей происходит без моего ведома. После использования Spring Boot какое-то время мне нужно было заглянуть под капот, чтобы снова чувствовать себя в безопасности — не так сильно под — просто достаточно, чтобы вернуться в свою зону комфорта.
Высокий уровень просмотра
Основной механизм выглядит так:
Все волшебные бины регистрируются в Spring-конфигурациях ( @Configuration
).
Но они загружаются только при соблюдении определенных условий, а именно:
- Обязательный класс доступен на пути к классам (новые бины волшебным образом создаются при добавлении зависимости).
- Требуемый компонент не был явно создан программистом.
Например, для загрузки, WebMvcAutoConfiguration
когда Servlet
, DispatcherServlet
и WebMvcConfigurerAdapter
классы находятся в пути к классам, тогда @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurerAdapter.class })
используется.
Эта конфигурация загружает все веб-настройки MVC по умолчанию, но, опять же, для большинства из них, только если конкретный компонент еще не существует.
Так, например, для проверки, если defaultViewResolver()
должен быть создан, @ConditionalOnMissingBean(InternalResourceViewResolver.class)
используется.
@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
WebMvcConfigurerAdapter.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
(...)
public class WebMvcAutoConfiguration {
(...)
@Bean
@ConditionalOnMissingBean(InternalResourceViewResolver.class)
public InternalResourceViewResolver defaultViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix(this.prefix);
resolver.setSuffix(this.suffix);
return resolver;
}
(...)
}
Где это срабатывает?
Все начинается с того @SpringBootApplication
, с которым вы комментируете свой основной класс. Если вы проверите его источник, вы обнаружите @EnableAutoConfiguration
там, и это ответственно за большую часть магии.
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);
application.run(args);
}
}
Если вы проверите, spring-boot-autoconfigure.jar/META-INF/spring.factories
вы найдете org.springframework.boot.autoconfigure.EnableAutoConfiguration
свойство, которое указывает, какие автоматические конфигурации будут использоваться, чтобы «угадать» и создать требуемые компоненты.
Пример использования DB Magic
Итак, давайте выясним, как создаются необходимые компоненты для доступа к БД.
Для этого давайте не будем использовать org.springframework.boot:spring-boot-starter-data-jpa
зависимости в нашей витрине, а начнем с org.springframework.boot:spring-boot-starter
того, что посмотрим, какие зависимости необходимо добавить для создания приложения с поддержкой базы данных и как автоматически выполняются необходимые шаги.
Благодаря spring-boot-starter:1.2.6.RELEASE
зависимости я получил 22 bean-компонента, зарегистрированных Spring в моем приложении (18 bean-компонентов Spring + 4 специфичных для приложения bean-компонента). Нет dataSource
или transactionManager
среди них.
Я хочу добавить спящий объект в проект, чтобы включить org.hibernate:hibernate-entitymanager
зависимость компиляции.
Теперь JtaAutoConfiguration
с jta properties
бобами были добавлены, как javax.transaction.Transaction
появились на classpath.
Я надеялся HibernateJpaAutoConfiguration
поймать, но этот также требует:
LocalContainerEntityManagerFactoryBean
(предоставитьentityManager
)EnableTransactionManagement
(предоставитьtransactionManager
)
И то и другое можно найти в org.springframework:spring-orm
, так что давайте добавим эту зависимость в путь к классам.
Теперь Spring попытается загрузить HibernateJpaAutoConfiguration
, но для этого требуется dataSource
bean-компонент ( @Autowired
как личное поле), и мы все еще его упускаем.
Легко понять, что dataSource
будет создано DataSourceAutoConfiguration
(найдено в списке в spring.factories
).
Кажется, что здесь выполнены все условия, но DataSourceAutoConfiguration
класс еще не может быть загружен, так как он использует org.apache.tomcat.jdbc.pool.DataSourceProxy
, так что это зависит от org.apache.tomcat:tomcat-jdbc
. Давайте добавим это и к пути к классам.
Запустив приложение, мы видим, что приближаемся, так как это время hibernate.dialect
не может быть определено. Неудивительно, что Spring не смог определить это, поскольку мы не добавили никаких зависимых от БД зависимостей. Итак, давайте включим com.h2database:h2a
.
Кажется, все работает сейчас. К весне 54 зерна. Среди них:
- источник данных (
org.apache.tomcat.jdbc.pool.DataSource
добавленDataSourceAutoConfiguration.NonEmbeddedConfiguration.dataSource()
) - entityManagerFactory (-
org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
добавленоJpaBaseConfiguration.entityManagerFactory()
(родительHibernateJpaAutoConfiguration
)) org.springframework.orm.jpa.JpaTransactionManager
actionManager (- добавленоJpaBaseConfiguration.transactionManager()
(родительHibernateJpaAutoConfiguration
)
Зависимости приведены на диаграмме ниже:
Демонстрационный проект можно найти здесь .