1
1
См. исходники и дополнения (ENG): https://reflectoring.io/spring-boot-starter/
2
2
________________________________________________________________________________________________________________________
3
- ****** Разбиение Spring Boot приложения на модули ******
3
+ ### Разбиение Spring Boot приложения на модули
4
4
5
5
Каждый программный проект подходит к моменту, когда код необходимо разбить на модули. Это могут быть модули внутри
6
6
одной кодовой базы или модули, каждый из которых живет в своей собственной кодовой базе. В этой статье объясняются
7
7
некоторые функции Spring Boot, которые помогают разделить приложение Spring Boot на несколько модулей.
8
8
9
- Пример кода на GitHub - https://github.com/thombergs/code-examples/tree/master/spring-boot/modular
9
+ Пример [ кода на GitHub] ( https://github.com/thombergs/code-examples/tree/master/spring-boot/modular )
10
10
11
11
________________________________________________________________________________________________________________________
12
- *** Что такое модуль в Spring Boot? ***
12
+ #### Что такое модуль в Spring Boot?
13
13
14
14
Модуль в понимании этой статьи — это набор компонентов Spring, загружаемых в контекст приложения.
15
15
@@ -20,72 +20,64 @@ ________________________________________________________________________________
20
20
того пожелаем - https://reflectoring.io/spring-boot-gradle-multi-module/ .
21
21
22
22
________________________________________________________________________________________________________________________
23
- *** Варианты создания модулей ***
23
+ #### Варианты создания модулей
24
24
25
25
Основой модуля Spring является @Configuration аннотированный класс, аналогичный функции конфигурации Java Spring.
26
- Существует несколько способов определить, какие bean-компоненты должны быть загружены таким классом конфигурации -
27
- https://docs.spring.io/spring-framework/reference/core/beans/java.html.
26
+ Существует несколько способов определить, какие [ bean-компоненты должны быть загружены таким классом конфигурации] ( https://docs.spring.io/spring-framework/reference/core/beans/java.html ) .
28
27
29
28
________________________________________________________________________________________________________________________
30
- *** @ComponentScan ***
29
+ #### @ComponentScan
31
30
32
31
Самый простой способ создать модуль — использовать аннотацию @ComponentScan к классу конфигурации:
33
32
34
- ************************************************************************************************************************
35
- @Configuration
36
- @ComponentScan(basePackages = "io.reflectoring.booking")
37
- public class BookingModuleConfiguration {
38
- }
39
- ************************************************************************************************************************
33
+ @Configuration
34
+ @ComponentScan(basePackages = "io.reflectoring.booking")
35
+ public class BookingModuleConfiguration {
36
+ }
40
37
41
38
Если этот класс конфигурации выбран одним из механизмов импорта (описано ниже), он просмотрит все классы в пакете
42
- io.reflectoring.booking и загрузит экземпляр каждого класса, который помечен одной из стереотипных аннотаций Spring,
43
- в контекст приложения, см.
44
- https://github.com/spring-projects/spring-framework/tree/main/spring-context/src/main/java/org/springframework/stereotype.
39
+ io.reflectoring.booking и загрузит экземпляр каждого класса, который помечен [ одной из стереотипных аннотаций Spring,
40
+ в контекст приложения] ( https://github.com/spring-projects/spring-framework/tree/main/spring-context/src/main/java/org/springframework/stereotype ) .
45
41
46
42
Этот способ подходит, если вы всегда хотите загружать все классы пакета и его подпакеты в контекст приложения. Если
47
43
вам нужно больше контроля над тем, что загружать, читайте дальше.
48
44
49
45
________________________________________________________________________________________________________________________
50
- *** Определения @Bean ***
46
+ #### Определения @Bean
51
47
52
48
Функция конфигурации Java в Spring также предоставляет @Bean аннотацию для создания bean-компонентов, загружаемых в
53
49
контекст приложения:
54
50
55
- ************************************************************************************************************************
56
- @Configuration
57
- public class BookingModuleConfiguration {
58
-
59
- @Bean
60
- public BookingService bookingService(){
61
- return new BookingService();
62
- }
63
-
64
- // potentially more @Bean definitions ...
65
-
66
- }
67
- ************************************************************************************************************************
51
+ @Configuration
52
+ public class BookingModuleConfiguration {
53
+
54
+ @Bean
55
+ public BookingService bookingService(){
56
+ return new BookingService();
57
+ }
58
+
59
+ // potentially more @Bean definitions ...
60
+
61
+ }
68
62
69
63
Когда этот класс конфигурации импортируется, экземпляр BookingService будет создан и вставлен в контекст приложения.
70
64
Использование этого способа создания модуля дает более четкое представление о том, какие bean-компоненты на самом деле
71
65
загружены, поскольку у вас есть одно место для просмотра - в отличие от использования, @ComponentScan когда вам нужно
72
66
смотреть на стереотипные аннотации всех классов в пакете, чтобы увидеть, что происходит.
73
67
74
68
________________________________________________________________________________________________________________________
75
- *** Аннотации @ConditionalOn... ***
69
+ #### Аннотации @ConditionalOn ...
76
70
77
71
Если вам нужен еще более детальный контроль над тем, какие компоненты следует загружать в контекст приложения, вы
78
72
можете использовать @ConditionalOn ... аннотации Spring Boot:
79
73
80
- ************************************************************************************************************************
81
- @Configuration
82
- @ConditionalOnProperty(name = "io.reflectoring.security.enabled",
83
- havingValue = "true",
84
- matchIfMissing = true)
85
- public class SecurityModuleConfiguration {
86
- // @Bean definitions ...
87
- }
88
- ************************************************************************************************************************
74
+ @Configuration
75
+ @ConditionalOnProperty(name = "io.reflectoring.security.enabled",
76
+ havingValue = "true",
77
+ matchIfMissing = true)
78
+ public class SecurityModuleConfiguration {
79
+ // @Bean definitions ...
80
+ }
89
81
90
82
Установка свойства io.reflectoring.security.enabled теперь - false полностью отключит этот модуль.
91
83
@@ -98,102 +90,93 @@ bean-компонента в контексте приложения, см. http
98
90
@ConditionalOn ...
99
91
100
92
________________________________________________________________________________________________________________________
101
- *** Варианты импорта модулей ***
93
+ #### Варианты импорта модулей
102
94
103
95
Создав модуль, нам необходимо импортировать его в приложение.
104
96
105
97
________________________________________________________________________________________________________________________
106
- *** @Import ***
98
+ #### @Import
107
99
108
100
Самый простой способ — использовать аннотацию @Import :
109
101
110
- ************************************************************************************************************************
111
- @SpringBootApplication
112
- @Import(BookingModuleConfiguration.class)
113
- public class ModularApplication {
114
- // ...
115
- }
116
- ************************************************************************************************************************
102
+ @SpringBootApplication
103
+ @Import(BookingModuleConfiguration.class)
104
+ public class ModularApplication {
105
+ // ...
106
+ }
117
107
118
108
Это приведет к импорту класса BookingModuleConfiguration и всех связанных с ним bean-компонентов - независимо от того,
119
109
объявлены ли они с помощью аннотаций @ComponentScan или @Bean .
120
110
121
111
________________________________________________________________________________________________________________________
122
- *** Аннотации @Enable... ***
112
+ #### Аннотации @Enable ...
123
113
124
114
Spring Boot предоставляет набор аннотаций, каждая из которых импортирует определенный модуль. Примером является,
125
115
аннотация @EnableScheduling которая импортирует все Bean-компоненты, необходимые для работы подсистемы планирования и
126
116
ее аннотаций @Scheduled .
127
117
128
118
Мы можем использовать это сами, определив собственную аннотацию @EnableBookingModule :
129
119
130
- ************************************************************************************************************************
131
- @Retention(RetentionPolicy.RUNTIME)
132
- @Target({ElementType.TYPE})
133
- @Documented
134
- @Import(BookingModuleConfiguration.class)
135
- @Configuration
136
- public @interface EnableBookingModule {
137
- }
138
- ************************************************************************************************************************
120
+ @Retention(RetentionPolicy.RUNTIME)
121
+ @Target({ElementType.TYPE})
122
+ @Documented
123
+ @Import(BookingModuleConfiguration.class)
124
+ @Configuration
125
+ public @interface EnableBookingModule {
126
+ }
139
127
140
128
Аннотация используется следующим образом:
141
129
142
- ************************************************************************************************************************
143
- @SpringBootApplication
144
- @EnableBookingModule
145
- public class ModularApplication {
146
- // ...
147
- }
148
- ************************************************************************************************************************
130
+ @SpringBootApplication
131
+ @EnableBookingModule
132
+ public class ModularApplication {
133
+ // ...
134
+ }
149
135
150
136
Аннотация @EnableBookingModule на самом деле является просто оберткой вокруг аннотации @Import , которая импортирует наш
151
137
объект, BookingModuleConfiguration как и раньше. Однако если у нас есть модуль, состоящий более чем из одной
152
138
конфигурации, это удобный и выразительный способ объединить эти конфигурации в один модуль.
153
139
154
140
________________________________________________________________________________________________________________________
155
- *** Авто-конфигурация ***
141
+ #### Авто-конфигурация
156
142
157
143
Если мы хотим загрузить модуль автоматически вместо жесткого связывания импорта с исходным кодом, мы можем использовать
158
144
функцию автоматической настройки Spring Boot.
159
145
160
146
Чтобы включить модуль для автоматической настройки, поместите файл META-INF/spring.factories в путь к классам:
161
147
162
- ************************************************************************************************************************
163
- org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
164
- io.reflectoring.security.SecurityModuleConfiguration
165
- ************************************************************************************************************************
148
+ org.springframework.boot.autoconfigure.EnableAutoConfiguration = io.reflectoring.security.SecurityModuleConfiguration
166
149
167
150
Это импортирует класс SecurityModuleConfiguration и все его компоненты в контекст приложения.
168
151
169
152
Автоматическая настройка особенно удобна, если мы создаем сквозную задачу, которая будет использоваться во многих
170
153
приложениях Spring Boot. В этом случае мы можем даже построить на основе конфигурации отдельный стартовый модуль.
171
154
172
155
________________________________________________________________________________________________________________________
173
- *** Настройка модуля ***
156
+ #### Настройка модуля
174
157
175
158
Благодаря @ConfigurationProperties аннотации Spring Boot обеспечивает первоклассную поддержку для привязки внешних
176
159
параметров конфигурации к bean-компоненту Spring типобезопасным способом, см.
177
160
https://reflectoring.io/spring-boot-configuration-properties/
178
161
179
162
________________________________________________________________________________________________________________________
180
- *** Когда использовать какую стратегию импорта? ***
163
+ #### Когда использовать какую стратегию импорта?
181
164
182
165
В этой статье представлены основные возможности создания и импорта модулей в приложении Spring Boot. Но когда нам
183
166
следует использовать какой из этих вариантов?
184
167
185
168
________________________________________________________________________________________________________________________
186
- *** Использование @Import для бизнес-модулей ***
169
+ #### Использование @Import для бизнес-модулей
187
170
188
171
Для модулей, содержащих бизнес-логику, таких, как BookingModuleConfiguration из приведенных выше фрагментов кода, в
189
172
большинстве случаев достаточно статического импорта с аннотацией @Import . Обычно не имеет смысла не загружать
190
173
бизнес-модуль, поэтому нам не требуется никакого контроля над условиями его загрузки.
191
174
192
- !!! Обратите внимание: даже если модуль всегда загружен, он все равно имеет право существовать как модуль, поскольку,
193
- будучи модулем, он может жить в своем собственном пакете или даже в своем собственном JAR-файле.
175
+ !!! Обратите внимание: даже если модуль всегда загружен, он все равно имеет право существовать как модуль, поскольку,
176
+ будучи модулем, он может жить в своем собственном пакете или даже в своем собственном JAR-файле.
194
177
195
178
________________________________________________________________________________________________________________________
196
- *** Используйте автоматическую настройку для технических модулей ***
179
+ #### Используйте автоматическую настройку для технических модулей
197
180
198
181
С другой стороны, технические модули, как и SecurityModuleConfiguration вышеописанные, обычно обеспечивают некоторые
199
182
сквозные задачи, такие как ведение журнала, обработка исключений, авторизация или функции мониторинга, без которых
0 commit comments