Порівняння Spring та Spring Boot
У цьому уроці ми розглянемо різницю між стандартними платформами Spring і Spring Boot.
Ми зосередимося та обговоримо, чим модулі Spring, такі як MVC та Security, відрізняються при використанні в ядрі Spring у порівнянні з використанням з Boot.
2. Що таке весна?
Простіше кажучи, середовище Spring забезпечує всебічну підтримку інфраструктури для розробки програм Java .
Він містить деякі приємні функції, такі як використання залежностей, і готові модулі, такі як:
- Весна JDBC
- Весняний МВК
- Весняна безпека
- Весняний АОП
- Весняний ОРМ
- Весняний тест
Ці модулі можуть значно скоротити час розробки програми.
Наприклад, на зорі веб-розробки на Java нам потрібно було написати багато шаблонного коду, щоб вставити запис у джерело даних. Використовуючи JDBCTemplate модуля Spring JDBC, ми можемо скоротити його до кількох рядків коду за допомогою лише кількох конфігурацій.
3. Що таке Spring Boot?
Spring Boot - це, по суті, розширення середовища Spring, яке усуває стандартні конфігурації, необхідні для налаштування програми Spring.
У ньому використовується самовпевнений погляд на платформу Spring, який прокладає шлях до більш швидкої та ефективної екосистеми розробки .
Ось лише деякі з особливостей Spring Boot:
- Затверджені початкові залежності для спрощення складання та налаштування програми.
- Вбудований сервер для спрощення розгортання програм
- Метрики, перевірка працездатності та зовнішня конфігурація
- Автоматична конфігурація для функціональності Spring - скрізь, де це можливо
Давайте познайомимося з обома цими фреймворками крок за кроком.
4. Залежність Maven
Перш за все, давайте розглянемо мінімальні залежності, необхідні для створення веб-застосунку з використанням Spring:
dependency>
groupId>org.springframeworkgroupId>
artifactId>spring-webartifactId>
version>5.3.5version>
dependency>
dependency>
groupId>org.springframeworkgroupId>
artifactId>spring-webmvcartifactId>
version>5.3.5version>
dependency>
На відміну від Spring, Spring Boot вимагає лише одну залежність для запуску та запуску веб-застосунку:
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-webartifactId>
version>2.4.4version>
dependency>
Всі інші залежності автоматично додаються до остаточного архіву під час складання.
Ще один добрий приклад — тестування бібліотек. Зазвичай ми використовуємо набір бібліотек Spring Test, JUnit, Hamcrest та Mockito. У проекті Spring ми повинні додати всі ці бібліотеки як залежність.
Як альтернатива, у Spring Boot нам потрібна лише початкова залежність для тестування, щоб автоматично включати ці бібліотеки.
Spring Boot надає низку початкових залежностей для різних модулів Spring. Ось деякі з найчастіше використовуваних:
- весна-завантаження-стартер-дані-jpa
- весна-завантаження-стартер-безпека
- весняне завантаження-стартер-тест
- весна-завантаження-стартер-мережа
- весна-завантаження-стартер-thymeleaf
Для отримання повного списку стартерів також ознайомтеся з документацією Spring.
5. Конфігурація MVC
Давайте розглянемо конфігурацію, необхідну для створення веб-програми JSP з використанням як Spring, так і Spring Boot.
Spring вимагає визначення сервлета-диспетчера, відображення та інших допоміжних конфігурацій. Ми можемо зробити це, використовуючи або файл web.xml або клас Initializer :
public
class
MyWebAppInitializer
implements
WebApplicationInitializer
@Override
public
void
onStartup(ServletContext
container)
AnnotationConfigWebApplicationContext
context
=
new
AnnotationConfigWebApplicationContext();
context.setConfigLocation("com.foreach");
container.addListener(new
ContextLoaderListener(context));
ServletRegistration.Dynamic
dispatcher
=
container
.addServlet("dispatcher",
new
DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
>
>
Нам також потрібно додати анотацію @EnableWebMvc до класу @Configuration і визначити перетворювач подання для дозволу уявлень, що повертаються контролерами:
@EnableWebMvc
@Configuration
public
class
ClientWebConfig
implements
WebMvcConfigurer
@Bean
public
ViewResolver
viewResolver()
InternalResourceViewResolver
bean
=
new
InternalResourceViewResolver();
bean.setViewClass(JstlView.class);
bean.setPrefix("/WEB-INF/view/");
bean.setSuffix(".jsp");
return
bean;
>
>
Для порівняння, Spring Boot потребує всього кілька властивостей, щоб усе запрацювало після додавання веб-стартеру:
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
Вся наведена вище конфігурація Spring автоматично вмикається шляхом додавання веб-стартера Boot за допомогою процесу, що називається автонастроювання .
Це означає, що Spring Boot розгляне залежності, властивості та bean-компоненти, що існують у додатку, та включить налаштування на їх основі.
Звичайно, якщо ми захочемо додати власну конфігурацію користувача, то автоконфігурація Spring Boot відступить.
5.1. Налаштування механізму шаблонів
Тепер давайте дізнаємося, як налаштувати механізм шаблонів Thymeleaf як у Spring, так і Spring Boot.
У Spring нам потрібно додати залежність thymeleaf-spring5 та деякі конфігурації для перетворювача уявлень:
@Configuration
@EnableWebMvc
public
class
MvcWebConfig
implements
WebMvcConfigurer
@Autowired
private
ApplicationContext
applicationContext;
@Bean
public
SpringResourceTemplateResolver
templateResolver()
SpringResourceTemplateResolver
templateResolver
=
new
SpringResourceTemplateResolver();
templateResolver.setApplicationContext(applicationContext);
templateResolver.setPrefix("/WEB-INF/views/");
templateResolver.setSuffix(".html");
return
templateResolver;
>
@Bean
public
SpringTemplateEngine
templateEngine()
SpringTemplateEngine
templateEngine
=
new
SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.setEnableSpringELCompiler(true);
return
templateEngine;
>
@Override
public
void
configureViewResolvers(ViewResolverRegistry
registry)
ThymeleafViewResolver
resolver
=
new
ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
registry.viewResolver(resolver);
>
>
Spring Boot 1 вимагає лише залежності spring-boot-starter-thymeleaf , щоб увімкнути підтримку Thymeleaf у веб-застосунку. Через нові функції в Thymeleaf3.0 нам також необхідно додати тимелеаф-макет-діалект як залежність у веб-додатку Spring Boot 2. Як альтернативу ми можемо додати залежність spring-boot-starter-thymeleaf , яка подбає про все це за нас.
Як тільки залежності будуть встановлені, ми можемо додати шаблони до папки src/main/resources/templates і Spring Boot відобразить їх автоматично.
6. Конфігурація безпеки Spring
Для простоти ми побачимо, як базова HTTP-автентифікація за замовчуванням включається за допомогою цих фреймворків.
Давайте почнемо з розгляду залежностей та конфігурації, необхідні для включення безпеки за допомогою Spring.
Spring вимагає як стандартних залежностей spring-security-web, так і spring-security-config для налаштування безпеки в програмі.
Далі нам потрібно додати клас, який розширює WebSecurityConfigurerAdapter та використовує анотацію @EnableWebSecurity :
@Configuration
@EnableWebSecurity
public
class
CustomWebSecurityConfigurerAdapter
extends
WebSecurityConfigurerAdapter
@Autowired
public
void
configureGlobal(AuthenticationManagerBuilder
auth)
throws
Exception
auth.вMemoryAuthentication()
.withUser("user1")
.password(passwordEncoder()
.encode("user1Pass"))
.authorities("ROLE_USER");
>
@Override
protected
void
configure(HttpSecurity
http)
throws
Exception
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic();
>
@Bean
public
PasswordEncoder
passwordEncoder()
return
new
BCryptPasswordEncoder();
>
>
Тут ми використовуємо inMemoryAuthentication для налаштування автентифікації.
Spring Boot також вимагає цих залежностей, щоб змусити його працювати, але нам потрібно лише визначити залежність spring-boot-starter-security , так як це автоматично додасть всі відповідні залежності до класів. ``
Конфігурація безпеки в Spring Boot така сама, як і вище.
Щоб побачити, як можна налаштувати JPA як у Spring, так і Spring Boot, ми можемо ознайомитися з нашою статтею A Guide to JPA with Spring .
7. Початкове завантаження програми
Основна відмінність у початковому завантаженні програми в Spring та Spring Boot полягає в сервлеті. Spring використовує або web.xml , або SpringServletContainerInitializer як точку входу початкового завантаження.
З іншого боку, Spring Boot використовує лише функції Servlet 3 для початкового завантаження програми. Давайте поговоримо про це докладно.
7.1. Як Spring Bootstraps?
Spring підтримує як застарілий спосіб завантаження web.xml, так і останній метод Servlet 3+.
Давайте розглянемо підхід web.xml за кроками:
- Контейнер сервлетів читає web.xml.
- DispatcherServlet, визначений у файлі web.xml, створюється контейнером. ``
- DispatcherServlet створює WebApplicationContext, читаючи WEB-INF/-servlet.xml.
- Нарешті DispatcherServlet реєструє bean-компоненти, визначені в контексті програми.
Ось як Spring завантажується з використанням підходу Servlet 3+:
- Контейнер шукає класи, що реалізують ServletContainerInitializer і виконує їх.
- SpringServletContainerInitializer знаходить усі класи, що реалізують WebApplicationInitializer .
- WebApplicationInitializer створює контекст за допомогою класів XML або @Configuration.
- WebApplicationInitializer створює DispatcherServlet із раніше створеним контекстом.
7.2. Як завантажується Spring Boot?
Точка входу програми Spring Boot - це клас, анотований @ SpringBootApplication :
@SpringBootApplication
public
class
Application
public
static
void
main(String[]
args)
SpringApplication.run(Application.class,
args);
>
>
За промовчанням Spring Boot використовує вбудований контейнер для запуску програми. У цьому випадку Spring Boot використовує основну точку входу public static void для запуску вбудованого веб-сервера.
Він також дбає про прив'язку bean-компонентів Servlet, Filter і ServletContextInitializer з контексту застосування до вбудованого контейнера сервлетів.
Ще одна особливість Spring Boot полягає в тому, що автоматично сканує всі класи в одному пакеті або підпакетах основного класу на наявність компонентів.
Крім того, Spring Boot надає можливість розгортання у вигляді веб-архіву у зовнішньому контейнері. У цьому випадку нам потрібно розширити SpringBootServletInitializer:
@SpringBootApplication
public
class
Application
extends
SpringBootServletInitializer
// .
>
Тут зовнішній контейнер сервлета шукає клас Main, визначений у файлі META-INF веб-архіву, а SpringBootServletInitializer подбає про прив'язку Servlet, Filter і ServletContextInitializer.
8. Упаковка та розгортання
Нарешті, давайте подивимося, як можна запакувати і розгорнути програму. Обидві платформи підтримують загальні технології управління пакетами, такі як Maven і Gradle; проте коли справа доходить до розгортання, ці платформи дуже різняться.
Наприклад, плагін Spring Boot Maven забезпечує підтримку Spring Boot Maven. Він також дозволяє упаковувати файли jar або war-архіви, що виконуються, і запускати додаток «на місці».
Деякі з переваг Spring Boot у порівнянні зі Spring у контексті розгортання включають:
- Забезпечує вбудовану підтримку контейнерів
- Можливість незалежного запуску банок за допомогою команди java-jar
- Можливість унеможливити залежність, щоб уникнути потенційних конфліктів jar при розгортанні у зовнішньому контейнері.
- Можливість вказати активні профілі під час розгортання
- Генерація випадкових портів для інтеграційних тестів
9. Висновок
У цій статті ми дізналися про різницю між Spring і Spring Boot.
У двох словах можна сказати, що Spring Boot - це просто розширення самого Spring, що робить розробку, тестування та розгортання зручнішими.
№6. Spring. @Configuration vs @Component
Рубрика "Пишеш нісенітниця" триває :) Цікаві моменти. Чим відрізняється інструкція @Configuration від @Component? Чому конфігураційні класи не можна робити? Для @Configuration класів спринг завжди створює проксі, для @Component класів проксі не створює. А створює проксі для того щоб підтримувати Inter-Bean Dependency, це коли в конфіг класі щоб отримати бін якийсь інший, просто викликаємо його метод, де насправді цей метод не викликається безпосередньо, а викликається через проксі, в цій проксі біни кешуються, щоб не створювався щоразу новий об'єкт. На прикладі: Ось такий конфіг клас:
@Configuration
public
class
RootConfig
@Bean
public
HeroRepository
heroRepository()
return
new
HeroRepository();
>
@Bean
public
HeroService
heroService()
return
new
HeroService(heroRepository());
>
>
public
static
void
main(
String[] args )
ApplicationContext context =
new
AnnotationConfigApplicationContext(RootConfig.class);
HeroService service = context.getBean(HeroService.class);
HeroRepository repository = context.getBean(HeroRepository.class);
RootConfig rootConfig = context.getBean(RootConfig.class);
System.out.println(service.getRepository()
== repository);
System.out.println(rootConfig.getClass());
>
То побачимо, що буде true, і буде створена проксі. Тому що по дефолту скоуп біна Singleton, тобто коли спринг створює бін, він реєструє його в контексті, і потім інжектить скрізь один і той самий інстанс.Тому heroRepository, який вставив heroService, і той, який просто витягується з контексту context.getBean(HeroRepository.class); є одним і тим же екземпляром.
class
com.test.crud.config.RootConfig$$SpringCGLIB$$0
true
З анотацією @Component буде лише клас RootConfig, а з @Configuration буде проксі-сервер CGLIB, тобто екземпляр не RootConfig, а екземпляр класу CGLIB, який є розширеним із RootConfig змініть анотацію на @Component у конфігурації та запустіть main, насправді це буде false, під час створення нового HeroService цей метод просто викликається heroRepository(); Де цей метод просто повертає new HeroRepository(), тобто створюється новий об’єкт, але для того, щоб підтримувати область дії компонента Singleton за замовчуванням, spring дозволяє щось під назвою Inter-Bean Dependency, коли ми використовуємо @Configuration spring. бібліотека CGLIB, створює конфігурацію класу проксі, і в цьому проксі описує логіку, перевизначає методи @Bean і описує там логіку кешування компонента, тобто створює новий heroService, точніше, коли він викликає метод heroRepository(), він перевіряє, чи є вже створений bean new HeroRepository(); bean вже створено, він просто повертає його, тому він зберігає область Singleton, якщо ви змінюєте @Configuration на @Component, тоді сприймайте цю річ вимикає його, оскільки він не існує для @Component, він робить його звичайним компонентом, і ці компоненти називаються саме так. Це викликає інше питання: чи можна зробити класи конфігурації остаточними. Відповідь: Ні, це неможливо? Якщо зробити його final CGLIB не може його заекстендити, вилетить BeanDefinitionParsingException, а його потрібно заекстендити що б створити проксі, так само не можна робити final методи, тому що вони ожертву, так само не можна робити метод private, тому що CGLIB не зможе заобрести тому що він private, він його просто не побачить, не побачить він його тому, що предки не бачать приватних методів. Звідси нюанс, якщо змінити @Configuration на @Component то можна використовувати навіть private метод для бина і все буде працювати, контекст буде збиратися, просто не буде працювати ось ця фішка яка називається Inter-Bean Dependency. p.s. поправте якщо щось не так зрозумів =)
Питання для співбесіди з відповідями на Spring, SQL.
Всім привіт. Знаходжуся у процесі вивчення spring та sql. Реалізував простий CRUD додаток з використанням springMVC та JDBC API, потім трохи переробив за допомогою JDBC Template. Користувався PostgreSQL. Перегорнув понад 20 сторінок на форумі, зустрічав теми зі spring, проте там знаходяться питання щодо завдань, для закріплення. Прошу скинути посилання з питаннями - відповідями для співбесіди щодо spring та sql де їх (питання-відповідей) велика кількість. У браузері, знайшов пару англомовних і пару російськомовних сайтів, з гідних, в яких не більше 30-40 запитань. співбесід.
Дякую! До речі, ти на мою думку теж спринг вчив, і вже працюєш? Дай якісь рекомендації, під час співбесід, коли мова заходить про спринг. І наскільки потрібно занурюватися в цю тему.
Працюю.Але просочився без Спрінга :) Так, зараз бувають проекти і без нього, хоча більшість із ним. Запитують всього потроху. Починаючи з того, що таке взагалі Спрінг, що таке Спрінг Бут і чим він відрізняється від Спрінга :) Навіщо потрібен Спрінг Бут, чому з ним краще ніж без нього. Що таке інверсія управління та впровадження залежностей. Що таке Бін, їх типи та життєвий цикл. Методи застосування залежностей. Основні інструкції. Що таке репозиторій та ін. Чомусь саме за Спрингом усіх цікавить теорія. Я відразу казав що в Спрінг я не шарю. Можу зробити модель даних за ТЗ чи готовою базою. Можу зробити REST API. Все це більше за зразками, ніж виходячи з глибокого розуміння. На цьому від мене відставали:)
За SQL на Stepik є хороші тренажери і курси: https://stepik.org/course/63054/promo?search=784265170 - безкоштовний , пройшов 1-у частину, дуже зрозуміло і круто.
, у яких не більше 30-40 питань.
ці 30-40 питань покриють 80% питань на стажиста/джуна. Щоб закріпити і розширити теорію - роби практику, різні проекти, завдання, тільки невеликі, дискретні, що фокусуються на одній темі, оскільки пиляти навіть один маленький проект по всій красі це довго. За SQL є відповідні сайти тренажери, або курси -, наприклад на Udemy або Степіку, тренажери це sqlzoo, sql-ex, sql academy По спрингу знову ж таки є удемі, книга Spring in Action і практика, хелло ворлд на спринг мвс, потім на спринг буте, потім додати спринг дата, потім окремо спринг секюріті прикрутити і тд, фокусуючись на базових речах.Теорію без практики складно вивчити, відсутність практики миттєво проглядається у відповідях, крок ліворуч-праворуч від типового питання, яке можна зазубрити, і все, люди припливають. Щоб менше припливати - потрібна практика, крутити ці технології читати теорію або дивитися, кому що заходить. Це за цими двома темами, там є ще 20-30 рівнозначних по важливості, але це вже інша історія :)
