Как Spring понимает, что использует не *.jar, а Starter
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
# Как Spring понимает, что использует не *.jar, а Starter?
Этот вопрос касается механизма Spring Boot Starter'ов и того, как Spring Boot определяет и автоматически конфигурирует зависимости. Давайте разберемся.
Что такое Spring Boot Starter?
Starter — это специальная зависимость Spring Boot, которая:
- Содержит метаданные о нужных библиотеках
- Автоматически конфигурирует приложение
- Предоставляет sensible defaults (разумные настройки по умолчанию)
Структура обычного JAR vs Starter
Обычный JAR
my-library.jar
├── META-INF/
│ └── MANIFEST.MF (только описание артефакта)
└── com/example/
└── MyClass.class
Spring Boot Starter
spring-boot-starter-web.jar
├── META-INF/
│ ├── MANIFEST.MF
│ └── spring.factories (← ВОТ ЭТО КЛЮЧЕВОЕ!)
│ └── spring-configuration-metadata.json
├── (сам стартер НЕ содержит кода, только метаданные!)
Как Spring Boot определяет Starter: spring.factories
Основной механизм — файл META-INF/spring.factories:
# spring-boot-starter-web.jar META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration
# spring-boot-starter-data-jpa.jar
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
Spring Boot при запуске:
- Находит все
spring.factoriesна classpath - Загружает классы из
EnableAutoConfiguration - Применяет автоконфигурацию
Пример: Как работает spring-boot-starter-web
build.gradle:
dependencies {
implementation "org.springframework.boot:spring-boot-starter-web:3.2.0"
}
Что происходит при сборке:
1. Gradle скачивает spring-boot-starter-web.jar
2. Spring Boot находит META-INF/spring.factories
3. Видит: DispatcherServletAutoConfiguration, ...
4. Автоматически создает бины:
- DispatcherServlet
- RequestMappingHandlerMapping
- RequestMappingHandlerAdapter
- Jackson ObjectMapper для JSON
- ... и еще 50+ бинов
AutoConfiguration класс пример
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({DispatcherServlet.class})
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@AutoConfigureBefore({ServletWebServerFactoryAutoConfiguration.class})
public class DispatcherServletAutoConfiguration {
@Configuration
@Conditional(DispatcherServletRegistrationCondition.class)
@ConditionalOnClass(ServletRegistration.class)
protected static class DispatcherServletConfiguration {
@Bean(name = DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServlet dispatcherServlet(WebMvcProperties webMvcProperties) {
DispatcherServlet dispatcherServlet = new DispatcherServlet();
// Применяем свойства из application.yml
webMvcProperties.getDispatcher().ifPresent(dispatcherServlet::setDispatchOptionsRequest);
return dispatcherServlet;
}
@Bean
public ServletRegistrationBean<DispatcherServlet> dispatcherServletRegistration(
DispatcherServlet dispatcherServlet,
WebMvcProperties webMvcProperties,
ObjectProvider<MultipartConfigElement> multipartConfig) {
ServletRegistrationBean<DispatcherServlet> registration =
new ServletRegistrationBean<>(dispatcherServlet, "/");
registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
registration.setLoadOnStartup(
webMvcProperties.getServlet().getLoadOnStartup());
multipartConfig.ifAvailable(registration::setMultipartConfig);
return registration;
}
}
}
Как Spring Boot находит AutoConfiguration
// В Spring Boot Application Context инициализации:
1. SpringApplication.run() запускается
2. SpringApplication создает AnnotatedBeanDefinitionReader
3. BeanDefinitionParser находит аннотацию @SpringBootApplication
4. Которая содержит @EnableAutoConfiguration
5. @EnableAutoConfiguration включает AutoConfigurationImportSelector
6. AutoConfigurationImportSelector.selectImports():
- Использует SpringFactoriesLoader
- Загружает META-INF/spring.factories из всех JAR'ов
- Фильтрует по условиям (@ConditionalOnClass, etc.)
- Возвращает список AutoConfiguration классов
7. Spring регистрирует все AutoConfiguration классы как Configuration beans
8. Spring создает бины согласно AutoConfiguration
Условия автоконфигурации
Spring использует аннотации-условия:
@ConditionalOnClass(ClassName.class) // Если класс есть на classpath
@ConditionalOnMissingClass(ClassName.class) // Если класса НЕ т на classpath
@ConditionalOnBean(BeanType.class) // Если бин есть в контексте
@ConditionalOnMissingBean(BeanType.class) // Если бина нет в контексте
@ConditionalOnProperty(name = "prop") // Если свойство установлено
@ConditionalOnWebApplication // Если это веб приложение
@ConditionalOnExpression("#{...}") // SpEL выражение
Пример:
@Configuration
@ConditionalOnClass(DataSource.class) // Если JDBC на classpath
@ConditionalOnMissingBean(DataSource.class) // И нет кастомного DataSource
public class DataSourceAutoConfiguration {
@Bean
@ConditionalOnProperty("spring.datasource.url")
public DataSource dataSource(DataSourceProperties properties) {
return DataSourceBuilder.create()
.url(properties.getUrl())
.username(properties.getUsername())
.password(properties.getPassword())
.build();
}
}
Практический пример: spring-boot-starter-data-jpa
build.gradle:
dependencies {
implementation "org.springframework.boot:spring-boot-starter-data-jpa"
}
Что в spring.factories:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration
Что происходит:
1. HibernateJpaAutoConfiguration проверяет:
- @ConditionalOnClass(Entity.class, EntityManager.class)
- @ConditionalOnMissingBean(JpaVendorAdapter.class)
2. Если условия выполнены, создает:
- SessionFactory
- EntityManagerFactory
- PlatformTransactionManager
3. JpaRepositoriesAutoConfiguration проверяет:
- @ConditionalOnClass(JpaRepository.class)
- @ConditionalOnMissingBean(RepositoryConfigurationDelegate.class)
4. Если условия выполнены, включает:
- @EnableJpaRepositories
- Сканирует @Repository интерфейсы
- Создает прокси для каждого Repository
Как разработчик может видеть, какие AutoConfiguration используются
# При запуске с debug режимом:
java -jar application.jar --debug
Или в application.properties:
logging.level.org.springframework.boot.autoconfigure=DEBUG
Вывод:
=========================
AUTO-CONFIGURATION REPORT
=========================
Positive matches:
-----------
DispatcherServletAutoConfiguration matched:
- @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet' (OnClassCondition)
- @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition)
DataSourceAutoConfiguration matched:
- @ConditionalOnClass found required classes 'javax.sql.DataSource', 'org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType' (OnClassCondition)
- @ConditionalOnMissingBean (types: javax.sql.DataSource, javax.sql.XADataSource; SearchStrategy: all) did not find any beans (OnBeanCondition)
Negative matches:
-----------
DataSourceTransactionManagerAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.springframework.jdbc.support.JdbcTransactionManager' (OnClassCondition)
Отключение определенной AutoConfiguration
@SpringBootApplication(
exclude = {
DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class
}
)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Или в application.properties:
spring.autoconfigure.exclude=\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
Заключение
Spring Boot определяет Starter'ы через:
✅ spring.factories — метаданные с AutoConfiguration классами ✅ SpringFactoriesLoader — загружает spring.factories из всех JAR'ов ✅ AutoConfigurationImportSelector — регистрирует AutoConfiguration ✅ @ConditionalOn* аннотации — проверяют условия применения ✅ Sensible defaults — автоматическая конфигурация с разумными значениями
Это делает Spring Boot таким удобным: вместо ручной конфигурации десятков классов, вы просто добавляете одну строку в build.gradle!