1262 lines
126 KiB
HTML
1262 lines
126 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en" dir="ltr"><head><script src="/livereload.js?mindelay=10&v=2&port=1313&path=livereload" data-no-instant defer></script>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="robots" content="noindex, nofollow" />
|
||
<link rel="icon shortcut" href="/favicon.ico" sizes="32x32" />
|
||
<link rel="icon" href="/favicon.svg" type="image/svg+xml" id="favicon-svg" />
|
||
<link rel="icon" href="/favicon-16x16.png" type="image/png" sizes="16x16" />
|
||
<link rel="icon" href="/favicon-32x32.png" type="image/png" sizes="32x32" />
|
||
<link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180" />
|
||
<link fetchpriority="low" href="/site.webmanifest" rel="manifest" />
|
||
<title>CodeJava</title>
|
||
<meta name="description" content="PrerequisitesBefore diving in, make sure you’re comfortable with the following:
|
||
Java — solid understanding of the language Object-oriented programming — classes, methods and interfaces Databases — tables, primary keys, foreign keys, relationships, etc. SQL — ability to write basic SQL statements What is a Spring Framework?Spring is a popular framework for building Java applications. It has a lot of modules, each designed to handle a specific task. They are combined into a few different layers." /><link rel="canonical" href="http://localhost:1313/courses/spring-boot/" itemprop="url" />
|
||
|
||
<meta property="og:title" content="">
|
||
<meta
|
||
property="og:description"
|
||
content="
|
||
|
||
Learn Java programming
|
||
|
||
">
|
||
<meta
|
||
property="og:type"
|
||
content="
|
||
website
|
||
">
|
||
<meta property="og:url" content="http://localhost:1313/courses/spring-boot/">
|
||
|
||
|
||
<meta itemprop="name" content="CodeJava">
|
||
<meta itemprop="description" content="PrerequisitesBefore diving in, make sure you’re comfortable with the following:
|
||
Java — solid understanding of the language Object-oriented programming — classes, methods and interfaces Databases — tables, primary keys, foreign keys, relationships, etc. SQL — ability to write basic SQL statements What is a Spring Framework?Spring is a popular framework for building Java applications. It has a lot of modules, each designed to handle a specific task. They are combined into a few different layers.">
|
||
<meta itemprop="wordCount" content="2184">
|
||
<meta name="twitter:card" content="summary">
|
||
<meta name="twitter:title" content="CodeJava">
|
||
<meta name="twitter:description" content="PrerequisitesBefore diving in, make sure you’re comfortable with the following:
|
||
Java — solid understanding of the language Object-oriented programming — classes, methods and interfaces Databases — tables, primary keys, foreign keys, relationships, etc. SQL — ability to write basic SQL statements What is a Spring Framework?Spring is a popular framework for building Java applications. It has a lot of modules, each designed to handle a specific task. They are combined into a few different layers.">
|
||
<link href="/css/compiled/main.css" rel="stylesheet" />
|
||
<link href="/css/variables.css" rel="stylesheet" />
|
||
<link href="/css/custom.css" rel="stylesheet" />
|
||
|
||
|
||
|
||
|
||
<script>
|
||
|
||
|
||
function setTheme(theme) {
|
||
document.documentElement.classList.remove("light", "dark");
|
||
|
||
if (theme !== "light" && theme !== "dark") {
|
||
theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
||
}
|
||
|
||
document.documentElement.classList.add(theme);
|
||
document.documentElement.style.colorScheme = theme;
|
||
}
|
||
|
||
setTheme("color-theme" in localStorage ? localStorage.getItem("color-theme") : 'system')
|
||
|
||
</script>
|
||
|
||
<script>
|
||
|
||
|
||
if (localStorage.getItem('banner-closed')) {
|
||
document.documentElement.style.setProperty("--hextra-banner-height", "0px");
|
||
document.documentElement.classList.add("hextra-banner-hidden");
|
||
}
|
||
</script>
|
||
|
||
|
||
|
||
</head>
|
||
<body><div class="hextra-nav-container hx:sticky hx:top-0 hx:z-20 hx:w-full hx:bg-transparent hx:print:hidden">
|
||
<div
|
||
class="hextra-nav-container-blur hx:pointer-events-none hx:absolute hx:z-[-1] hx:h-full hx:w-full hx:bg-white hx:dark:bg-dark hx:shadow-[0_2px_4px_rgba(0,0,0,.02),0_1px_0_rgba(0,0,0,.06)] hx:contrast-more:shadow-[0_0_0_1px_#000] hx:dark:shadow-[0_-1px_0_rgba(255,255,255,.1)_inset] hx:contrast-more:dark:shadow-[0_0_0_1px_#fff]"
|
||
></div>
|
||
|
||
<nav class="hextra-max-navbar-width hx:mx-auto hx:flex hx:items-center hx:justify-end hx:gap-2 hx:h-16 hx:px-6">
|
||
<a class="hx:flex hx:items-center hx:hover:opacity-75 hx:ltr:mr-auto hx:rtl:ml-auto" href="/">
|
||
<img class="hx:mr-2 hx:block hx:dark:hidden" src="/images/logo.svg" alt="Logo" height="20" width="20" />
|
||
<img class="hx:mr-2 hx:hidden hx:dark:block" src="/images/logo.svg" alt="Dark Logo" height="20" width="20" />
|
||
<span class="hx:mr-2 hx:font-extrabold hx:inline hx:select-none" title="CodeJava">CodeJava</span>
|
||
</a>
|
||
<a
|
||
title=""
|
||
href="/courses"
|
||
|
||
class="hx:text-sm hx:contrast-more:text-gray-700 hx:contrast-more:dark:text-gray-100 hx:relative hx:-ml-2 hx:hidden hx:whitespace-nowrap hx:p-2 hx:md:inline-flex hx:items-center hx:gap-1 hx:font-medium"
|
||
><span class="hx:text-center">Courses</span>
|
||
</a><div class="hextra-search-wrapper hx:relative hx:md:w-64">
|
||
<div class="hx:relative hx:flex hx:items-center hx:text-gray-900 hx:contrast-more:text-gray-800 hx:dark:text-gray-300 hx:contrast-more:dark:text-gray-300">
|
||
<input
|
||
placeholder="Search..."
|
||
class="hextra-search-input hx:focus:hextra-focus hx:block hx:w-full hx:appearance-none hx:rounded-lg hx:px-3 hx:py-2 hx:transition-colors hx:text-base hx:leading-tight hx:md:text-sm hx:bg-black/[.05] hx:dark:bg-gray-50/10 hx:focus:bg-white hx:dark:focus:bg-dark hx:placeholder:text-gray-500 hx:dark:placeholder:text-gray-400 hx:contrast-more:border hx:contrast-more:border-current"
|
||
type="search"
|
||
value=""
|
||
spellcheck="false"
|
||
/>
|
||
<kbd
|
||
class="hx:absolute hx:my-1.5 hx:select-none hx:ltr:right-1.5 hx:rtl:left-1.5 hx:h-5 hx:rounded-sm hx:bg-white hx:px-1.5 hx:font-mono hx:text-[10px] hx:font-medium hx:text-gray-500 hx:border hx:border-gray-200 hx:dark:border-gray-100/20 hx:dark:bg-dark/50 hx:contrast-more:border-current hx:contrast-more:text-current hx:contrast-more:dark:border-current hx:items-center hx:gap-1 hx:transition-opacity hx:pointer-events-none hx:hidden hx:sm:flex"
|
||
>
|
||
CTRL K
|
||
</kbd>
|
||
</div>
|
||
|
||
<div>
|
||
<ul
|
||
class="hextra-search-results hextra-scrollbar hx:hidden hx:border hx:border-gray-200 hx:bg-white hx:text-gray-100 hx:dark:border-neutral-800 hx:dark:bg-neutral-900 hx:absolute hx:top-full hx:z-20 hx:mt-2 hx:overflow-auto hx:overscroll-contain hx:rounded-xl hx:py-2.5 hx:shadow-xl hx:max-h-[min(calc(50vh-11rem-env(safe-area-inset-bottom)),400px)] hx:md:max-h-[min(calc(100vh-5rem-env(safe-area-inset-bottom)),400px)] hx:inset-x-0 hx:ltr:md:left-auto hx:rtl:md:right-auto hx:contrast-more:border hx:contrast-more:border-gray-900 hx:contrast-more:dark:border-gray-50 hx:w-screen hx:min-h-[100px] hx:max-w-[min(calc(100vw-2rem),calc(100%+20rem))]"
|
||
style="transition: max-height 0.2s ease 0s;"
|
||
></ul>
|
||
</div>
|
||
</div>
|
||
<button type="button" aria-label="Menu" class="hextra-hamburger-menu hx:cursor-pointer hx:-mr-2 hx:rounded-sm hx:p-2 hx:active:bg-gray-400/20 hx:md:hidden"><svg height=24 fill="none" viewBox="0 0 24 24" stroke="currentColor"><g><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8H20"></path></g><g><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16H20"></path></g></svg></button>
|
||
</nav>
|
||
</div>
|
||
|
||
<div class='hx:mx-auto hx:flex hextra-max-page-width'>
|
||
<aside class="hextra-sidebar-container hx:flex hx:flex-col hx:print:hidden hx:md:top-16 hx:md:shrink-0 hx:md:w-64 hx:md:self-start hx:max-md:[transform:translate3d(0,-100%,0)] hx:md:sticky">
|
||
|
||
<div class="hx:px-4 hx:pt-4 hx:md:hidden">
|
||
<div class="hextra-search-wrapper hx:relative hx:md:w-64">
|
||
<div class="hx:relative hx:flex hx:items-center hx:text-gray-900 hx:contrast-more:text-gray-800 hx:dark:text-gray-300 hx:contrast-more:dark:text-gray-300">
|
||
<input
|
||
placeholder="Search..."
|
||
class="hextra-search-input hx:focus:hextra-focus hx:block hx:w-full hx:appearance-none hx:rounded-lg hx:px-3 hx:py-2 hx:transition-colors hx:text-base hx:leading-tight hx:md:text-sm hx:bg-black/[.05] hx:dark:bg-gray-50/10 hx:focus:bg-white hx:dark:focus:bg-dark hx:placeholder:text-gray-500 hx:dark:placeholder:text-gray-400 hx:contrast-more:border hx:contrast-more:border-current"
|
||
type="search"
|
||
value=""
|
||
spellcheck="false"
|
||
/>
|
||
<kbd
|
||
class="hx:absolute hx:my-1.5 hx:select-none hx:ltr:right-1.5 hx:rtl:left-1.5 hx:h-5 hx:rounded-sm hx:bg-white hx:px-1.5 hx:font-mono hx:text-[10px] hx:font-medium hx:text-gray-500 hx:border hx:border-gray-200 hx:dark:border-gray-100/20 hx:dark:bg-dark/50 hx:contrast-more:border-current hx:contrast-more:text-current hx:contrast-more:dark:border-current hx:items-center hx:gap-1 hx:transition-opacity hx:pointer-events-none hx:hidden hx:sm:flex"
|
||
>
|
||
CTRL K
|
||
</kbd>
|
||
</div>
|
||
|
||
<div>
|
||
<ul
|
||
class="hextra-search-results hextra-scrollbar hx:hidden hx:border hx:border-gray-200 hx:bg-white hx:text-gray-100 hx:dark:border-neutral-800 hx:dark:bg-neutral-900 hx:absolute hx:top-full hx:z-20 hx:mt-2 hx:overflow-auto hx:overscroll-contain hx:rounded-xl hx:py-2.5 hx:shadow-xl hx:max-h-[min(calc(50vh-11rem-env(safe-area-inset-bottom)),400px)] hx:md:max-h-[min(calc(100vh-5rem-env(safe-area-inset-bottom)),400px)] hx:inset-x-0 hx:ltr:md:left-auto hx:rtl:md:right-auto hx:contrast-more:border hx:contrast-more:border-gray-900 hx:contrast-more:dark:border-gray-50 hx:w-screen hx:min-h-[100px] hx:max-w-[min(calc(100vw-2rem),calc(100%+20rem))]"
|
||
style="transition: max-height 0.2s ease 0s;"
|
||
></ul>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
<div class="hextra-scrollbar hx:overflow-y-auto hx:overflow-x-hidden hx:p-4 hx:grow hx:md:h-[calc(100vh-var(--navbar-height)-var(--menu-height))]">
|
||
<ul class="hx:flex hx:flex-col hx:gap-1 hx:md:hidden">
|
||
|
||
|
||
<li class="open"><a
|
||
class="hx:flex hx:items-center hx:justify-between hx:gap-2 hx:cursor-pointer hx:rounded-sm hx:px-2 hx:py-1.5 hx:text-sm hx:transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word]
|
||
hx:text-gray-500 hx:hover:bg-gray-100 hx:hover:text-gray-900 hx:contrast-more:border hx:contrast-more:border-transparent hx:contrast-more:text-gray-900 hx:contrast-more:hover:border-gray-900 hx:dark:text-neutral-400 hx:dark:hover:bg-primary-100/5 hx:dark:hover:text-gray-50 hx:contrast-more:dark:text-gray-50 hx:contrast-more:dark:hover:border-gray-50"
|
||
href="/courses/"
|
||
|
||
>Courses
|
||
<span class="hextra-sidebar-collapsible-button"><svg fill="none" viewBox="0 0 24 24" stroke="currentColor" class="hx:h-[18px] hx:min-w-[18px] hx:rounded-xs hx:p-0.5 hx:hover:bg-gray-800/5 hx:dark:hover:bg-gray-100/5"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" class="hx:origin-center hx:transition-transform hx:rtl:-rotate-180"></path></svg></span>
|
||
</a><div class="hx:ltr:pr-0 hx:overflow-hidden">
|
||
<ul class='hx:relative hx:flex hx:flex-col hx:gap-1 hx:before:absolute hx:before:inset-y-1 hx:before:w-px hx:before:bg-gray-200 hx:before:content-[""] hx:ltr:ml-3 hx:ltr:pl-3 hx:ltr:before:left-0 hx:rtl:mr-3 hx:rtl:pr-3 hx:rtl:before:right-0 hx:dark:before:bg-neutral-800'><li class="hx:flex hx:flex-col open"><a
|
||
class="hx:flex hx:items-center hx:justify-between hx:gap-2 hx:cursor-pointer hx:rounded-sm hx:px-2 hx:py-1.5 hx:text-sm hx:transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word]
|
||
hextra-sidebar-active-item hx:bg-primary-100 hx:font-semibold hx:text-primary-800 hx:contrast-more:border hx:contrast-more:border-primary-500 hx:dark:bg-primary-400/10 hx:dark:text-primary-600 hx:contrast-more:dark:border-primary-500"
|
||
href="/courses/spring-boot/"
|
||
|
||
>Spring Boot
|
||
</a>
|
||
|
||
<ul class='hx:flex hx:flex-col hx:gap-1 hx:relative hx:before:absolute hx:before:inset-y-1 hx:before:w-px hx:before:bg-gray-200 hx:before:content-[""] hx:dark:before:bg-neutral-800 hx:ltr:pl-3 hx:ltr:before:left-0 hx:rtl:pr-3 hx:rtl:before:right-0 hx:ltr:ml-3 hx:rtl:mr-3'><li>
|
||
<a
|
||
href="#setter-injection"
|
||
class="hx:flex hx:rounded-sm hx:px-2 hx:py-1.5 hx:text-sm hx:transition-colors [word-break:break-word] hx:cursor-pointer [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] hx:contrast-more:border hx:gap-2 hx:before:opacity-25 hx:before:content-['#'] hx:text-gray-500 hx:hover:bg-gray-100 hx:hover:text-gray-900 hx:dark:text-neutral-400 hx:dark:hover:bg-primary-100/5 hx:dark:hover:text-gray-50 hx:contrast-more:text-gray-900 hx:contrast-more:dark:text-gray-50 hx:contrast-more:border-transparent hx:contrast-more:hover:border-gray-900 hx:contrast-more:dark:hover:border-gray-50"
|
||
>Setter Injection</a>
|
||
</li>
|
||
</ul>
|
||
|
||
|
||
</li><li class="hx:flex hx:flex-col "><a
|
||
class="hx:flex hx:items-center hx:justify-between hx:gap-2 hx:cursor-pointer hx:rounded-sm hx:px-2 hx:py-1.5 hx:text-sm hx:transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word]
|
||
hx:text-gray-500 hx:hover:bg-gray-100 hx:hover:text-gray-900 hx:contrast-more:border hx:contrast-more:border-transparent hx:contrast-more:text-gray-900 hx:contrast-more:hover:border-gray-900 hx:dark:text-neutral-400 hx:dark:hover:bg-primary-100/5 hx:dark:hover:text-gray-50 hx:contrast-more:dark:text-gray-50 hx:contrast-more:dark:hover:border-gray-50"
|
||
href="/courses/prog-intro/"
|
||
|
||
>Introduction to Programming in Java
|
||
<span class="hextra-sidebar-collapsible-button"><svg fill="none" viewBox="0 0 24 24" stroke="currentColor" class="hx:h-[18px] hx:min-w-[18px] hx:rounded-xs hx:p-0.5 hx:hover:bg-gray-800/5 hx:dark:hover:bg-gray-100/5"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" class="hx:origin-center hx:transition-transform hx:rtl:-rotate-180"></path></svg></span>
|
||
</a>
|
||
<div class="hx:ltr:pr-0 hx:overflow-hidden">
|
||
<ul class='hx:relative hx:flex hx:flex-col hx:gap-1 hx:before:absolute hx:before:inset-y-1 hx:before:w-px hx:before:bg-gray-200 hx:before:content-[""] hx:ltr:ml-3 hx:ltr:pl-3 hx:ltr:before:left-0 hx:rtl:mr-3 hx:rtl:pr-3 hx:rtl:before:right-0 hx:dark:before:bg-neutral-800'><li class="hx:flex hx:flex-col "><a
|
||
class="hx:flex hx:items-center hx:justify-between hx:gap-2 hx:cursor-pointer hx:rounded-sm hx:px-2 hx:py-1.5 hx:text-sm hx:transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word]
|
||
hx:text-gray-500 hx:hover:bg-gray-100 hx:hover:text-gray-900 hx:contrast-more:border hx:contrast-more:border-transparent hx:contrast-more:text-gray-900 hx:contrast-more:hover:border-gray-900 hx:dark:text-neutral-400 hx:dark:hover:bg-primary-100/5 hx:dark:hover:text-gray-50 hx:contrast-more:dark:text-gray-50 hx:contrast-more:dark:hover:border-gray-50"
|
||
href="/courses/prog-intro/homeworks/"
|
||
|
||
>Homeworks
|
||
</a>
|
||
|
||
</li><li class="hx:flex hx:flex-col "><a
|
||
class="hx:flex hx:items-center hx:justify-between hx:gap-2 hx:cursor-pointer hx:rounded-sm hx:px-2 hx:py-1.5 hx:text-sm hx:transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word]
|
||
hx:text-gray-500 hx:hover:bg-gray-100 hx:hover:text-gray-900 hx:contrast-more:border hx:contrast-more:border-transparent hx:contrast-more:text-gray-900 hx:contrast-more:hover:border-gray-900 hx:dark:text-neutral-400 hx:dark:hover:bg-primary-100/5 hx:dark:hover:text-gray-50 hx:contrast-more:dark:text-gray-50 hx:contrast-more:dark:hover:border-gray-50"
|
||
href="/courses/prog-intro/lectures/"
|
||
|
||
>Lectures
|
||
<span class="hextra-sidebar-collapsible-button"><svg fill="none" viewBox="0 0 24 24" stroke="currentColor" class="hx:h-[18px] hx:min-w-[18px] hx:rounded-xs hx:p-0.5 hx:hover:bg-gray-800/5 hx:dark:hover:bg-gray-100/5"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" class="hx:origin-center hx:transition-transform hx:rtl:-rotate-180"></path></svg></span>
|
||
</a>
|
||
<div class="hx:ltr:pr-0 hx:overflow-hidden">
|
||
<ul class='hx:relative hx:flex hx:flex-col hx:gap-1 hx:before:absolute hx:before:inset-y-1 hx:before:w-px hx:before:bg-gray-200 hx:before:content-[""] hx:ltr:ml-3 hx:ltr:pl-3 hx:ltr:before:left-0 hx:rtl:mr-3 hx:rtl:pr-3 hx:rtl:before:right-0 hx:dark:before:bg-neutral-800'><li class="hx:flex hx:flex-col "><a
|
||
class="hx:flex hx:items-center hx:justify-between hx:gap-2 hx:cursor-pointer hx:rounded-sm hx:px-2 hx:py-1.5 hx:text-sm hx:transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word]
|
||
hx:text-gray-500 hx:hover:bg-gray-100 hx:hover:text-gray-900 hx:contrast-more:border hx:contrast-more:border-transparent hx:contrast-more:text-gray-900 hx:contrast-more:hover:border-gray-900 hx:dark:text-neutral-400 hx:dark:hover:bg-primary-100/5 hx:dark:hover:text-gray-50 hx:contrast-more:dark:text-gray-50 hx:contrast-more:dark:hover:border-gray-50"
|
||
href="/courses/prog-intro/lectures/intro/"
|
||
|
||
>Lecture 1. Introduction
|
||
</a>
|
||
|
||
</li></ul>
|
||
</div>
|
||
</li></ul>
|
||
</div>
|
||
</li><li class="hx:flex hx:flex-col "><a
|
||
class="hx:flex hx:items-center hx:justify-between hx:gap-2 hx:cursor-pointer hx:rounded-sm hx:px-2 hx:py-1.5 hx:text-sm hx:transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word]
|
||
hx:text-gray-500 hx:hover:bg-gray-100 hx:hover:text-gray-900 hx:contrast-more:border hx:contrast-more:border-transparent hx:contrast-more:text-gray-900 hx:contrast-more:hover:border-gray-900 hx:dark:text-neutral-400 hx:dark:hover:bg-primary-100/5 hx:dark:hover:text-gray-50 hx:contrast-more:dark:text-gray-50 hx:contrast-more:dark:hover:border-gray-50"
|
||
href="/courses/paradigms/"
|
||
|
||
>Paradgims of Programming
|
||
</a>
|
||
|
||
</li></ul>
|
||
</div></li>
|
||
</ul>
|
||
|
||
<ul class="hx:flex hx:flex-col hx:gap-1 hx:max-md:hidden">
|
||
|
||
<li class="open"><a
|
||
class="hx:flex hx:items-center hx:justify-between hx:gap-2 hx:cursor-pointer hx:rounded-sm hx:px-2 hx:py-1.5 hx:text-sm hx:transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word]
|
||
hextra-sidebar-active-item hx:bg-primary-100 hx:font-semibold hx:text-primary-800 hx:contrast-more:border hx:contrast-more:border-primary-500 hx:dark:bg-primary-400/10 hx:dark:text-primary-600 hx:contrast-more:dark:border-primary-500"
|
||
href="/courses/spring-boot/"
|
||
|
||
>Spring Boot
|
||
</a></li>
|
||
<li class=""><a
|
||
class="hx:flex hx:items-center hx:justify-between hx:gap-2 hx:cursor-pointer hx:rounded-sm hx:px-2 hx:py-1.5 hx:text-sm hx:transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word]
|
||
hx:text-gray-500 hx:hover:bg-gray-100 hx:hover:text-gray-900 hx:contrast-more:border hx:contrast-more:border-transparent hx:contrast-more:text-gray-900 hx:contrast-more:hover:border-gray-900 hx:dark:text-neutral-400 hx:dark:hover:bg-primary-100/5 hx:dark:hover:text-gray-50 hx:contrast-more:dark:text-gray-50 hx:contrast-more:dark:hover:border-gray-50"
|
||
href="/courses/prog-intro/"
|
||
|
||
>Introduction to Programming in Java
|
||
<span class="hextra-sidebar-collapsible-button"><svg fill="none" viewBox="0 0 24 24" stroke="currentColor" class="hx:h-[18px] hx:min-w-[18px] hx:rounded-xs hx:p-0.5 hx:hover:bg-gray-800/5 hx:dark:hover:bg-gray-100/5"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" class="hx:origin-center hx:transition-transform hx:rtl:-rotate-180"></path></svg></span>
|
||
</a><div class="hx:ltr:pr-0 hx:overflow-hidden">
|
||
<ul class='hx:relative hx:flex hx:flex-col hx:gap-1 hx:before:absolute hx:before:inset-y-1 hx:before:w-px hx:before:bg-gray-200 hx:before:content-[""] hx:ltr:ml-3 hx:ltr:pl-3 hx:ltr:before:left-0 hx:rtl:mr-3 hx:rtl:pr-3 hx:rtl:before:right-0 hx:dark:before:bg-neutral-800'><li class="hx:flex hx:flex-col "><a
|
||
class="hx:flex hx:items-center hx:justify-between hx:gap-2 hx:cursor-pointer hx:rounded-sm hx:px-2 hx:py-1.5 hx:text-sm hx:transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word]
|
||
hx:text-gray-500 hx:hover:bg-gray-100 hx:hover:text-gray-900 hx:contrast-more:border hx:contrast-more:border-transparent hx:contrast-more:text-gray-900 hx:contrast-more:hover:border-gray-900 hx:dark:text-neutral-400 hx:dark:hover:bg-primary-100/5 hx:dark:hover:text-gray-50 hx:contrast-more:dark:text-gray-50 hx:contrast-more:dark:hover:border-gray-50"
|
||
href="/courses/prog-intro/homeworks/"
|
||
|
||
>Homeworks
|
||
</a>
|
||
|
||
</li><li class="hx:flex hx:flex-col "><a
|
||
class="hx:flex hx:items-center hx:justify-between hx:gap-2 hx:cursor-pointer hx:rounded-sm hx:px-2 hx:py-1.5 hx:text-sm hx:transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word]
|
||
hx:text-gray-500 hx:hover:bg-gray-100 hx:hover:text-gray-900 hx:contrast-more:border hx:contrast-more:border-transparent hx:contrast-more:text-gray-900 hx:contrast-more:hover:border-gray-900 hx:dark:text-neutral-400 hx:dark:hover:bg-primary-100/5 hx:dark:hover:text-gray-50 hx:contrast-more:dark:text-gray-50 hx:contrast-more:dark:hover:border-gray-50"
|
||
href="/courses/prog-intro/lectures/"
|
||
|
||
>Lectures
|
||
<span class="hextra-sidebar-collapsible-button"><svg fill="none" viewBox="0 0 24 24" stroke="currentColor" class="hx:h-[18px] hx:min-w-[18px] hx:rounded-xs hx:p-0.5 hx:hover:bg-gray-800/5 hx:dark:hover:bg-gray-100/5"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" class="hx:origin-center hx:transition-transform hx:rtl:-rotate-180"></path></svg></span>
|
||
</a>
|
||
<div class="hx:ltr:pr-0 hx:overflow-hidden">
|
||
<ul class='hx:relative hx:flex hx:flex-col hx:gap-1 hx:before:absolute hx:before:inset-y-1 hx:before:w-px hx:before:bg-gray-200 hx:before:content-[""] hx:ltr:ml-3 hx:ltr:pl-3 hx:ltr:before:left-0 hx:rtl:mr-3 hx:rtl:pr-3 hx:rtl:before:right-0 hx:dark:before:bg-neutral-800'><li class="hx:flex hx:flex-col "><a
|
||
class="hx:flex hx:items-center hx:justify-between hx:gap-2 hx:cursor-pointer hx:rounded-sm hx:px-2 hx:py-1.5 hx:text-sm hx:transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word]
|
||
hx:text-gray-500 hx:hover:bg-gray-100 hx:hover:text-gray-900 hx:contrast-more:border hx:contrast-more:border-transparent hx:contrast-more:text-gray-900 hx:contrast-more:hover:border-gray-900 hx:dark:text-neutral-400 hx:dark:hover:bg-primary-100/5 hx:dark:hover:text-gray-50 hx:contrast-more:dark:text-gray-50 hx:contrast-more:dark:hover:border-gray-50"
|
||
href="/courses/prog-intro/lectures/intro/"
|
||
|
||
>Lecture 1. Introduction
|
||
</a>
|
||
|
||
</li></ul>
|
||
</div>
|
||
</li></ul>
|
||
</div></li>
|
||
<li class=""><a
|
||
class="hx:flex hx:items-center hx:justify-between hx:gap-2 hx:cursor-pointer hx:rounded-sm hx:px-2 hx:py-1.5 hx:text-sm hx:transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word]
|
||
hx:text-gray-500 hx:hover:bg-gray-100 hx:hover:text-gray-900 hx:contrast-more:border hx:contrast-more:border-transparent hx:contrast-more:text-gray-900 hx:contrast-more:hover:border-gray-900 hx:dark:text-neutral-400 hx:dark:hover:bg-primary-100/5 hx:dark:hover:text-gray-50 hx:contrast-more:dark:text-gray-50 hx:contrast-more:dark:hover:border-gray-50"
|
||
href="/courses/paradigms/"
|
||
|
||
>Paradgims of Programming
|
||
</a></li>
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
|
||
<div class=" hx:sticky hx:bottom-0 hx:max-h-(--menu-height) hx:bg-white hx:dark:bg-dark hx:mx-4 hx:py-4 hx:shadow-[0_-12px_16px_#fff] hx:flex hx:items-center hx:gap-2 hx:border-gray-200 hx:dark:border-neutral-800 hx:dark:shadow-[0_-12px_16px_#111] hx:contrast-more:border-neutral-400 hx:contrast-more:shadow-none hx:contrast-more:dark:shadow-none hx:border-t" data-toggle-animation="show"><div class="hx:flex hx:grow hx:flex-col"><div class="hx:flex hx:justify-items-start hx:group" data-theme="light">
|
||
<button
|
||
title="Change theme"
|
||
data-state="closed"
|
||
data-location="bottom"
|
||
class="hextra-theme-toggle hx:cursor-pointer hx:rounded-md hx:text-left hx:font-medium hx:h-7 hx:px-2 hx:text-xs hx:hover:bg-gray-100 hx:hover:text-gray-900 hx:dark:hover:bg-primary-100/5 hx:dark:hover:text-gray-50 hx:font-medium hx:text-gray-600 hx:transition-colors hx:dark:text-gray-400 hx:grow"
|
||
type="button"
|
||
aria-label="Change theme"
|
||
>
|
||
<div class="hx:flex hx:items-center hx:gap-2 hx:capitalize"><svg height=12 class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"/></svg><span class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden">Light</span><svg height=12 class="hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/></svg><span class="hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden">Dark</span><svg height=12 class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
|
||
<path d="M 11.996094,2 C 6.4986225,2.0192368 2.03125,6.5024993 2.03125,12 c 0,5.497501 4.4673725,9.980763 9.964844,10 H 12 12.0039 c 5.497471,-0.01924 9.964844,-4.502499 9.964844,-10 0,-5.4975007 -4.467373,-9.9807632 -9.964844,-10 H 12 Z M 12,4 c 4.417218,0.017598 7.96875,3.5822356 7.96875,8 0,4.417764 -3.551532,7.982402 -7.96875,8 z" />
|
||
</svg>
|
||
<span class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden">System</span></div>
|
||
</button>
|
||
<ul
|
||
class="hextra-theme-toggle-options hx:hidden hx:z-20 hx:max-h-64 hx:overflow-auto hx:rounded-md hx:ring-1 hx:ring-black/5 hx:bg-white hx:py-1 hx:text-sm hx:shadow-lg hx:dark:ring-white/20 hx:dark:bg-neutral-800"
|
||
style="position: fixed; inset: auto auto 0px 0px; margin: 0px; min-width: 100px;"
|
||
data-theme="light"
|
||
>
|
||
<li class="hx:flex hx:flex-col">
|
||
<p
|
||
data-item="light"
|
||
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||
>
|
||
Light
|
||
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||
</p>
|
||
</li>
|
||
<li class="hx:flex hx:flex-col">
|
||
<p
|
||
data-item="dark"
|
||
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||
>
|
||
Dark
|
||
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||
</p>
|
||
</li>
|
||
<li class="hx:flex hx:flex-col">
|
||
<p
|
||
data-item="system"
|
||
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||
>
|
||
System
|
||
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||
</p>
|
||
</li>
|
||
</ul>
|
||
</div></div></div></aside>
|
||
|
||
<nav class="hextra-toc hx:order-last hx:hidden hx:w-64 hx:shrink-0 hx:xl:block hx:print:hidden hx:px-4" aria-label="table of contents">
|
||
<div class="hextra-scrollbar hx:sticky hx:top-16 hx:overflow-y-auto hx:pr-4 hx:pt-6 hx:text-sm [hyphens:auto] hx:max-h-[calc(100vh-var(--navbar-height)-env(safe-area-inset-bottom))] hx:ltr:-mr-4 hx:rtl:-ml-4"><p class="hx:mb-4 hx:font-semibold hx:tracking-tight">On this page</p><ul></ul><ul></ul><ul></ul><ul></ul><ul></ul><ul></ul><ul>
|
||
<li class="hx:my-2 hx:scroll-my-6 hx:scroll-py-6">
|
||
<a class="hx:font-medium hx:inline-block hx:text-gray-500 hx:hover:text-gray-900 hx:dark:text-gray-400 hx:dark:hover:text-gray-300 hx:contrast-more:text-gray-900 hx:contrast-more:underline hx:contrast-more:dark:text-gray-50 hx:w-full hx:break-words" href="#setter-injection">Setter Injection
|
||
</a>
|
||
</li></ul>
|
||
<div class="hx:mt-8 hx:border-t hx:bg-white hx:pt-8 hx:shadow-[0_-12px_16px_white] hx:dark:bg-dark hx:dark:shadow-[0_-12px_16px_#111] hx:sticky hx:bottom-0 hx:flex hx:flex-col hx:items-start hx:gap-2 hx:pb-8 hx:border-gray-200 hx:dark:border-neutral-800 hx:contrast-more:border-t hx:contrast-more:border-neutral-400 hx:contrast-more:shadow-none hx:contrast-more:dark:border-neutral-400">
|
||
<button aria-hidden="true" id="backToTop" onClick="scrollUp();" class="hx:cursor-pointer hx:transition-all hx:duration-75 hx:opacity-0 hx:text-xs hx:font-medium hx:text-gray-500 hx:hover:text-gray-900 hx:dark:text-gray-400 hx:dark:hover:text-gray-100 hx:contrast-more:text-gray-800 hx:contrast-more:dark:text-gray-50">
|
||
<span>Scroll to top</span>
|
||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="hx:inline hx:ltr:ml-1 hx:rtl:mr-1 hx:h-3.5 hx:w-3.5 hx:rounded-full hx:border hx:border-gray-500 hx:hover:border-gray-900 hx:dark:border-gray-400 hx:dark:hover:border-gray-100 hx:contrast-more:border-gray-800 hx:contrast-more:dark:border-gray-50">
|
||
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 15.75l7.5-7.5 7.5 7.5" />
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
|
||
|
||
<article class="hx:w-full hx:break-words hx:flex hx:min-h-[calc(100vh-var(--navbar-height))] hx:min-w-0 hx:justify-center hx:pb-8 hx:pr-[calc(env(safe-area-inset-right)-1.5rem)]">
|
||
<main class="hx:w-full hx:min-w-0 hx:max-w-6xl hx:px-6 hx:pt-4 hx:md:px-12">
|
||
|
||
<div class="content">
|
||
|
||
<h1>Prerequisites</h1><p>Before diving in, make sure you’re comfortable with the following:</p>
|
||
<ul>
|
||
<li><strong>Java</strong> — solid understanding of the language</li>
|
||
<li><strong>Object-oriented programming</strong> — classes, methods and interfaces</li>
|
||
<li><strong>Databases</strong> — tables, primary keys, foreign keys, relationships, etc.</li>
|
||
<li><strong>SQL</strong> — ability to write basic SQL statements</li>
|
||
</ul>
|
||
<hr>
|
||
<h1>What is a Spring Framework?</h1><p><strong>Spring</strong> is a popular framework for building Java applications. It has a lot of modules, each designed to handle a specific task. They are combined into a few different layers.</p>
|
||
<p><img src="assets/spring-layers.svg" alt="Spring layers" loading="lazy" />
|
||
<em>Img. 1 — Spring layers</em></p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th><strong>Layer</strong></th>
|
||
<th><strong>Purpose</strong></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><em>Core</em></td>
|
||
<td>Handling dependency injection, managing objects</td>
|
||
</tr>
|
||
<tr>
|
||
<td><em>Web</em></td>
|
||
<td>Building web applications</td>
|
||
</tr>
|
||
<tr>
|
||
<td><em>Data</em></td>
|
||
<td>Working with databases</td>
|
||
</tr>
|
||
<tr>
|
||
<td><em>AOP</em></td>
|
||
<td>Aspect oriented programming</td>
|
||
</tr>
|
||
<tr>
|
||
<td><em>Test</em></td>
|
||
<td>Testing spring components</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<hr>
|
||
<p>While the Spring Framework is powerful, using it often involves a lot of configuration. For example, if you want to build a web app you might need to setup a web server, configure routing and manage dependencies manually. That’s when <strong>Spring Boot</strong> comes in.</p>
|
||
<div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:flex-col hx:rounded-lg hx:border hx:py-4 hx:px-4 hx:border-gray-200 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200">
|
||
<p class="hx:flex hx:items-center hx:font-medium"><svg height=16px class="hx:inline-block hx:align-middle hx:mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>Note</p>
|
||
|
||
<div class="hx:w-full hx:min-w-0 hx:leading-7">
|
||
<div class="hx:mt-6 hx:leading-7 hx:first:mt-0"><p>You can think of Spring Boot as a layer on top of the Spring Framework that takes care of all of the setup. <em>Spring Boot</em> simplifies Spring development by providing sensible defaults and ready-to-use features.</p></div>
|
||
</div>
|
||
</div>
|
||
<p>By the way, the Spring Framework is just one part of a larger family of projects in the <strong>Spring ecosystem</strong>.</p>
|
||
<p><img src="assets/spring-ecosystem.svg" alt="Spring ecosystem" loading="lazy" />
|
||
<em>Img. 2 — Spring ecosystem</em></p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th><strong>Module Name</strong></th>
|
||
<th><strong>Purpose</strong></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><em>Spring Data</em></td>
|
||
<td>Simplifying database access</td>
|
||
</tr>
|
||
<tr>
|
||
<td><em>Spring Security</em></td>
|
||
<td>Adding authentication and authorization</td>
|
||
</tr>
|
||
<tr>
|
||
<td><em>Spring Batch</em></td>
|
||
<td>Batch processing</td>
|
||
</tr>
|
||
<tr>
|
||
<td><em>Spring Cloud</em></td>
|
||
<td>Building microservices and distributed systems</td>
|
||
</tr>
|
||
<tr>
|
||
<td><em>Spring Integration</em></td>
|
||
<td>Simplifying messaging and integration between systems</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<hr>
|
||
<h1>Initialize Spring Boot Project</h1><p>To initialize a new Spring Boot project, go to <a href="https://start.spring.io/"target="_blank" rel="noopener">start.spring.io</a> and select the options that suit you.</p>
|
||
<p><img src="assets/spring-project-init.png" alt="Spring Options" loading="lazy" />
|
||
<em>Img. 3 — Spring Boot options</em></p>
|
||
<p>After unpacking the <code>zip</code> archive, you’ll have this template project:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>.
|
||
</span></span><span style="display:flex;"><span>├── HELP.md
|
||
</span></span><span style="display:flex;"><span>├── mvnw
|
||
</span></span><span style="display:flex;"><span>├── mvnw.cmd
|
||
</span></span><span style="display:flex;"><span>├── pom.xml
|
||
</span></span><span style="display:flex;"><span>├── src
|
||
</span></span><span style="display:flex;"><span>│ ├── main
|
||
</span></span><span style="display:flex;"><span>│ │ ├── java
|
||
</span></span><span style="display:flex;"><span>│ │ │ └── tech
|
||
</span></span><span style="display:flex;"><span>│ │ │ └── codejava
|
||
</span></span><span style="display:flex;"><span>│ │ │ └── store
|
||
</span></span><span style="display:flex;"><span>│ │ │ └── StoreApplication.java
|
||
</span></span><span style="display:flex;"><span>│ │ └── resources
|
||
</span></span><span style="display:flex;"><span>│ │ └── application.properties
|
||
</span></span><span style="display:flex;"><span>│ └── test
|
||
</span></span><span style="display:flex;"><span>│ └── java
|
||
</span></span><span style="display:flex;"><span>│ └── tech
|
||
</span></span><span style="display:flex;"><span>│ └── codejava
|
||
</span></span><span style="display:flex;"><span>│ └── store
|
||
</span></span><span style="display:flex;"><span>│ └── StoreApplicationTests.java
|
||
</span></span><span style="display:flex;"><span>└── target
|
||
</span></span><span style="display:flex;"><span> ├── classes
|
||
</span></span><span style="display:flex;"><span> │ ├── application.properties
|
||
</span></span><span style="display:flex;"><span> │ └── tech
|
||
</span></span><span style="display:flex;"><span> │ └── codejava
|
||
</span></span><span style="display:flex;"><span> │ └── store
|
||
</span></span><span style="display:flex;"><span> │ └── StoreApplication.class
|
||
</span></span><span style="display:flex;"><span> ├── generated-sources
|
||
</span></span><span style="display:flex;"><span> │ └── annotations
|
||
</span></span><span style="display:flex;"><span> ├── generated-test-sources
|
||
</span></span><span style="display:flex;"><span> │ └── test-annotations
|
||
</span></span><span style="display:flex;"><span> ├── maven-status
|
||
</span></span><span style="display:flex;"><span> │ └── maven-compiler-plugin
|
||
</span></span><span style="display:flex;"><span> │ ├── compile
|
||
</span></span><span style="display:flex;"><span> │ │ └── default-compile
|
||
</span></span><span style="display:flex;"><span> │ │ ├── createdFiles.lst
|
||
</span></span><span style="display:flex;"><span> │ │ └── inputFiles.lst
|
||
</span></span><span style="display:flex;"><span> │ └── testCompile
|
||
</span></span><span style="display:flex;"><span> │ └── default-testCompile
|
||
</span></span><span style="display:flex;"><span> │ ├── createdFiles.lst
|
||
</span></span><span style="display:flex;"><span> │ └── inputFiles.lst
|
||
</span></span><span style="display:flex;"><span> ├── surefire-reports
|
||
</span></span><span style="display:flex;"><span> │ ├── TEST-tech.codejava.store.StoreApplicationTests.xml
|
||
</span></span><span style="display:flex;"><span> │ └── tech.codejava.store.StoreApplicationTests.txt
|
||
</span></span><span style="display:flex;"><span> └── test-classes
|
||
</span></span><span style="display:flex;"><span> └── tech
|
||
</span></span><span style="display:flex;"><span> └── codejava
|
||
</span></span><span style="display:flex;"><span> └── store
|
||
</span></span><span style="display:flex;"><span> └── StoreApplicationTests.class</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>The “heart” of our project is <code>pom.xml</code>:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#75715e"><?xml version="1.0" encoding="UTF-8" ?></span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672"><project</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">xmlns=</span><span style="color:#e6db74">"http://maven.apache.org/POM/4.0.0"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">xmlns:xsi=</span><span style="color:#e6db74">"http://www.w3.org/2001/XMLSchema-instance"</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">xsi:schemaLocation=</span><span style="color:#e6db74">"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><modelVersion></span>4.0.0<span style="color:#f92672"></modelVersion></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><parent></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><groupId></span>org.springframework.boot<span style="color:#f92672"></groupId></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><artifactId></span>spring-boot-starter-parent<span style="color:#f92672"></artifactId></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><version></span>4.0.2<span style="color:#f92672"></version></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><relativePath</span> <span style="color:#f92672">/></span> <span style="color:#75715e"><!-- lookup parent from repository --></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"></parent></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><groupId></span>tech.codejava<span style="color:#f92672"></groupId></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><artifactId></span>store<span style="color:#f92672"></artifactId></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><version></span>0.0.1-SNAPSHOT<span style="color:#f92672"></version></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><name></span>store<span style="color:#f92672"></name></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><description></span>Store<span style="color:#f92672"></description></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><url</span> <span style="color:#f92672">/></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><licenses></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><license</span> <span style="color:#f92672">/></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"></licenses></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><developers></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><developer</span> <span style="color:#f92672">/></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"></developers></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><scm></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><connection</span> <span style="color:#f92672">/></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><developerConnection</span> <span style="color:#f92672">/></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><tag</span> <span style="color:#f92672">/></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><url</span> <span style="color:#f92672">/></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"></scm></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><properties></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><java.version></span>21<span style="color:#f92672"></java.version></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"></properties></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><dependencies></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><dependency></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><groupId></span>org.springframework.boot<span style="color:#f92672"></groupId></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><artifactId></span>spring-boot-starter<span style="color:#f92672"></artifactId></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"></dependency></span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><dependency></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><groupId></span>org.springframework.boot<span style="color:#f92672"></groupId></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><artifactId></span>spring-boot-starter-test<span style="color:#f92672"></artifactId></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><scope></span>test<span style="color:#f92672"></scope></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"></dependency></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"></dependencies></span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><build></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><plugins></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><plugin></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><groupId></span>org.springframework.boot<span style="color:#f92672"></groupId></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><artifactId></span>spring-boot-maven-plugin<span style="color:#f92672"></artifactId></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"></plugin></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"></plugins></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"></build></span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672"></project></span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>Maven uses this file to download dependencies and build our project.</p>
|
||
<p>In the <code>src</code> folder we have the actual code:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>src
|
||
</span></span><span style="display:flex;"><span>├── main
|
||
</span></span><span style="display:flex;"><span>│ ├── java
|
||
</span></span><span style="display:flex;"><span>│ │ └── tech
|
||
</span></span><span style="display:flex;"><span>│ │ └── codejava
|
||
</span></span><span style="display:flex;"><span>│ │ └── store
|
||
</span></span><span style="display:flex;"><span>│ │ └── StoreApplication.java
|
||
</span></span><span style="display:flex;"><span>│ └── resources
|
||
</span></span><span style="display:flex;"><span>│ └── application.properties
|
||
</span></span><span style="display:flex;"><span>└── test
|
||
</span></span><span style="display:flex;"><span> └── java
|
||
</span></span><span style="display:flex;"><span> └── tech
|
||
</span></span><span style="display:flex;"><span> └── codejava
|
||
</span></span><span style="display:flex;"><span> └── store
|
||
</span></span><span style="display:flex;"><span> └── StoreApplicationTests.java</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p><code>StoreApplication.java</code> is the entry point to our application:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> tech.codejava.store;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.springframework.boot.SpringApplication;
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.springframework.boot.autoconfigure.SpringBootApplication;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@SpringBootApplication</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">StoreApplication</span> {
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">main</span>(String<span style="color:#f92672">[]</span> args) {
|
||
</span></span><span style="display:flex;"><span> SpringApplication.<span style="color:#a6e22e">run</span>(StoreApplication.<span style="color:#a6e22e">class</span>, args);
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>In the <code>main</code> method we have a call to <code>SpringApplication.run</code>.</p>
|
||
<p>Running <code>mvn clean install</code> from the root of our project gives us this result <em>(output partially reduced)</em>:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>...
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.542 s -- in tech.codejava.store.StoreApplicationTests
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> Results:
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> Tests run: 1, Failures: 0, Errors: 0, Skipped: <span style="color:#ae81ff">0</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> --- jar:3.4.2:jar <span style="color:#f92672">(</span>default-jar<span style="color:#f92672">)</span> @ store ---
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> Building jar: /home/fymio/store/target/store-0.0.1-SNAPSHOT.jar
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> --- spring-boot:4.0.2:repackage <span style="color:#f92672">(</span>repackage<span style="color:#f92672">)</span> @ store ---
|
||
</span></span><span style="display:flex;"><span>...
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> BUILD SUCCESS
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> ------------------------------------------------------------------------
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> Total time: 14.787 s
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> Finished at: 2026-02-19T13:16:47+03:00
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> ------------------------------------------------------------------------</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>Our application built without errors.</p>
|
||
<hr>
|
||
<h1>Dependency Management</h1><p>Dependencies are third-party libraries or frameworks we use in our application. For example, to build a web application we need an embedded web server like <em>Tomcat</em>, libraries for handling web requests, building APIs, processing JSON data, logging and so on.</p>
|
||
<p>In Spring Boot applications, instead of adding multiple individual libraries, we can use a <strong>starter dependency</strong>.</p>
|
||
<p><img src="assets/spring-boot-starter-web.svg" alt="Spring Boot Starter Web" loading="lazy" />
|
||
<em>Img. 5 — Spring Boot Starter Web</em></p>
|
||
<p>To use this dependency, copy the following into your <code>pom.xml</code>:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#f92672"><dependency></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><groupId></span>org.springframework.boot<span style="color:#f92672"></groupId></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><artifactId></span>spring-boot-starter-web<span style="color:#f92672"></artifactId></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><version></span>4.1.0-M1<span style="color:#f92672"></version></span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672"></dependency></span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>So the <code>dependencies</code> section would look like this:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#f92672"><dependencies></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><dependency></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><groupId></span>org.springframework.boot<span style="color:#f92672"></groupId></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><artifactId></span>spring-boot-starter<span style="color:#f92672"></artifactId></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"></dependency></span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><dependency></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><groupId></span>org.springframework.boot<span style="color:#f92672"></groupId></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><artifactId></span>spring-boot-starter-test<span style="color:#f92672"></artifactId></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><scope></span>test<span style="color:#f92672"></scope></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"></dependency></span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><dependency></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><groupId></span>org.springframework.boot<span style="color:#f92672"></groupId></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"><artifactId></span>spring-boot-starter-web<span style="color:#f92672"></artifactId></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e"><!-- <version>4.1.0-M1</version> --></span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#f92672"></dependency></span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672"></dependencies></span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:flex-col hx:rounded-lg hx:border hx:py-4 hx:px-4 hx:border-gray-200 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-purple-200 hx:bg-purple-100 hx:text-purple-900 hx:dark:border-purple-200/30 hx:dark:bg-purple-900/30 hx:dark:text-purple-200">
|
||
<p class="hx:flex hx:items-center hx:font-medium"><svg height=16px class="hx:inline-block hx:align-middle hx:mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>Important</p>
|
||
|
||
<div class="hx:w-full hx:min-w-0 hx:leading-7">
|
||
<div class="hx:mt-6 hx:leading-7 hx:first:mt-0"><p>Notice that the version is commented out. It’s a better practice to let Spring Boot decide what version of the dependency to use, as it ensures compatibility across your project.</p></div>
|
||
</div>
|
||
</div>
|
||
<hr>
|
||
<h1>Controllers</h1><p><strong>Spring MVC</strong> stands for <em>Model View Controller</em>.</p>
|
||
<ul>
|
||
<li><strong>Model</strong> is where our application’s data lives. It represents the business logic and is usually connected to a database or other data sources. In Spring Boot, the model can be a simple Java class.</li>
|
||
<li><strong>View</strong> is what the user sees. It’s the HTML, CSS or JavaScript rendered in the browser. In Spring MVC, views can be static files or dynamically generated.</li>
|
||
<li><strong>Controller</strong> is like a traffic controller. It handles incoming requests from the user, interacts with the model to get data and then tells the view what to display.</li>
|
||
</ul>
|
||
<p>Let’s add a new Java class called <code>HomeController</code> at <code>src/main/java/tech/codejava/store/HomeController.java</code>:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> tech.codejava.store;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">HomeController</span> {}</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>To make this a controller, decorate it with the <code>@Controller</code> annotation:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> tech.codejava.store;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.springframework.stereotype.Controller;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@Controller</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">HomeController</span> {}</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>Now let’s add an <code>index</code> method. When we send a request to the root of our website, we want this method to be called:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> tech.codejava.store;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.springframework.stereotype.Controller;
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.springframework.web.bind.annotation.RequestMapping;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@Controller</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">HomeController</span> {
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">@RequestMapping</span>(<span style="color:#e6db74">"/"</span>) <span style="color:#75715e">// this represents the root of our website</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> String <span style="color:#a6e22e">index</span>() {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#e6db74">"index.html"</span>; <span style="color:#75715e">// this returns the view</span>
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>Now we need to create the view. Add <code>index.html</code> at <code>src/main/resources/static/index.html</code>:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span><span style="color:#75715e"><!doctype html></span>
|
||
</span></span><span style="display:flex;"><span><<span style="color:#f92672">html</span> <span style="color:#a6e22e">lang</span><span style="color:#f92672">=</span><span style="color:#e6db74">"en"</span>>
|
||
</span></span><span style="display:flex;"><span> <<span style="color:#f92672">head</span>>
|
||
</span></span><span style="display:flex;"><span> <<span style="color:#f92672">meta</span> <span style="color:#a6e22e">charset</span><span style="color:#f92672">=</span><span style="color:#e6db74">"UTF-8"</span> />
|
||
</span></span><span style="display:flex;"><span> <<span style="color:#f92672">meta</span> <span style="color:#a6e22e">name</span><span style="color:#f92672">=</span><span style="color:#e6db74">"viewport"</span> <span style="color:#a6e22e">content</span><span style="color:#f92672">=</span><span style="color:#e6db74">"width=device-width, initial-scale=1.0"</span> />
|
||
</span></span><span style="display:flex;"><span> <<span style="color:#f92672">title</span>>View</<span style="color:#f92672">title</span>>
|
||
</span></span><span style="display:flex;"><span> </<span style="color:#f92672">head</span>>
|
||
</span></span><span style="display:flex;"><span> <<span style="color:#f92672">body</span>>
|
||
</span></span><span style="display:flex;"><span> <<span style="color:#f92672">h1</span>>Hello world!</<span style="color:#f92672">h1</span>>
|
||
</span></span><span style="display:flex;"><span> </<span style="color:#f92672">body</span>>
|
||
</span></span><span style="display:flex;"><span></<span style="color:#f92672">html</span>></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>Let’s build and run our application using <code>mvn spring-boot:run</code>. From the logs:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>2026-02-19T14:55:23.948+03:00 INFO <span style="color:#ae81ff">36752</span> --- <span style="color:#f92672">[</span>store<span style="color:#f92672">]</span> <span style="color:#f92672">[</span> main<span style="color:#f92672">]</span> o.s.boot.tomcat.TomcatWebServer : Tomcat initialized with port <span style="color:#ae81ff">8080</span> <span style="color:#f92672">(</span>http<span style="color:#f92672">)</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>Our app is up and running at <a href="http://localhost:8080/"target="_blank" rel="noopener">localhost:8080</a>.</p>
|
||
<p><img src="assets/hello-world.png" alt="Hello world!" loading="lazy" />
|
||
<em>Img. 7 — Our app is up and running!</em></p>
|
||
<hr>
|
||
<h1>Configuring Application Properties</h1><p>Let’s take a look at <code>src/main/resources/application.properties</code>:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span><span style="color:#a6e22e">spring.application.name</span><span style="color:#f92672">=</span><span style="color:#e6db74">store</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>To use this property in our code, we can use the <code>@Value</code> annotation. Let’s update <code>HomeController</code> to print the application name:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> tech.codejava.store;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.springframework.beans.factory.annotation.Value;
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.springframework.stereotype.Controller;
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.springframework.web.bind.annotation.RequestMapping;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@Controller</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">HomeController</span> {
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">@Value</span>(<span style="color:#e6db74">"${spring.application.name}"</span>)
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">private</span> String appName;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">@RequestMapping</span>(<span style="color:#e6db74">"/"</span>) <span style="color:#75715e">// this represents the root of our website</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> String <span style="color:#a6e22e">index</span>() {
|
||
</span></span><span style="display:flex;"><span> System.<span style="color:#a6e22e">out</span>.<span style="color:#a6e22e">println</span>(<span style="color:#e6db74">"application name = "</span> <span style="color:#f92672">+</span> appName);
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#e6db74">"index.html"</span>; <span style="color:#75715e">// this returns the view</span>
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>After running the application, we can see <code>store</code> printed in the terminal:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>...
|
||
</span></span><span style="display:flex;"><span>2026-02-19T15:32:37.507+03:00 INFO <span style="color:#ae81ff">41536</span> --- <span style="color:#f92672">[</span>store<span style="color:#f92672">]</span> <span style="color:#f92672">[</span>nio-8080-exec-1<span style="color:#f92672">]</span> o.s.web.servlet.DispatcherServlet : Initializing Servlet <span style="color:#e6db74">'dispatcherServlet'</span>
|
||
</span></span><span style="display:flex;"><span>2026-02-19T15:32:37.509+03:00 INFO <span style="color:#ae81ff">41536</span> --- <span style="color:#f92672">[</span>store<span style="color:#f92672">]</span> <span style="color:#f92672">[</span>nio-8080-exec-1<span style="color:#f92672">]</span> o.s.web.servlet.DispatcherServlet : Completed initialization in <span style="color:#ae81ff">2</span> ms
|
||
</span></span><span style="display:flex;"><span>application name <span style="color:#f92672">=</span> store
|
||
</span></span><span style="display:flex;"><span>...</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<hr>
|
||
<h1>Dependency Injection</h1><p>Imagine we’re building an E-Commerce application that handles placing orders. When an order is placed, the customer’s payment needs to be processed — so <code>OrderService</code> depends on a payment service like <code>StripePaymentService</code>. We can say that <code>OrderService</code> is <em>dependent on</em> (or <em>coupled to</em>) <code>StripePaymentService</code>.</p>
|
||
<p><img src="assets/depends-on-coupled-to.svg" alt="Depends on/Coupled to relation" loading="lazy" />
|
||
<em>Img. 8 — Depends On/Coupled To relation</em></p>
|
||
<p>Let’s talk about the issues that arise when one class is <strong>tightly coupled</strong> to another.</p>
|
||
<ol>
|
||
<li><strong>Inflexibility</strong> — <code>OrderService</code> can only use <code>StripePaymentService</code>. If tomorrow we decide to switch to a different payment provider like PayPal, we would have to modify <code>OrderService</code>. Once we change it, it has to be recompiled and retested, which could impact other classes that depend on it.</li>
|
||
<li><strong>Untestability</strong> — We cannot test <code>OrderService</code> in isolation, because <code>OrderService</code> is tightly coupled with <code>StripePaymentService</code> and we can’t test its logic separately from it.</li>
|
||
</ol>
|
||
<div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:flex-col hx:rounded-lg hx:border hx:py-4 hx:px-4 hx:border-gray-200 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200">
|
||
<p class="hx:flex hx:items-center hx:font-medium"><svg height=16px class="hx:inline-block hx:align-middle hx:mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>Note</p>
|
||
|
||
<div class="hx:w-full hx:min-w-0 hx:leading-7">
|
||
<div class="hx:mt-6 hx:leading-7 hx:first:mt-0"><p>The problem here isn’t that <code>OrderService</code> <em>depends</em> on <code>StripePaymentService</code> — dependencies are normal in any application. The issue is about <em>how</em> the dependency is created and managed.</p></div>
|
||
</div>
|
||
</div>
|
||
<p><strong>Analogy:</strong> Think of a restaurant. A restaurant needs a chef — that’s a perfectly normal dependency. If the current chef becomes unavailable, the restaurant can hire another one.</p>
|
||
<p><img src="assets/restaurant-chef-dependency.svg" alt="Restaurant — Chef dependency" loading="lazy" />
|
||
<em>Img. X — Restaurant — Chef dependency (Normal)</em></p>
|
||
<p>Now what if we replace “chef” with a specific person: John? Our restaurant is now dependent on <em>John specifically</em>. If John becomes unavailable, we can’t replace him — the restaurant is in trouble. This is an example of <strong>tight</strong> or <strong>bad coupling</strong>.</p>
|
||
<p><img src="assets/restaurant-john-dependency.svg" alt="Restaurant — John dependency" loading="lazy" />
|
||
<em>Img. X — Restaurant — John dependency (Bad coupling)</em></p>
|
||
<p>We don’t want <code>OrderService</code> to be tightly coupled to a specific payment service like Stripe. Instead, we want it to depend on a <code>PaymentService</code> <em>interface</em>, which could be Stripe, PayPal, or any other provider. To achieve this we can use the <em>interface</em> to decouple <code>OrderService</code> from <code>StripePaymentService</code>.</p>
|
||
<p><img src="assets/payment-service-as-interface.svg" alt="Payment Service as interface" loading="lazy" />
|
||
<em>Img. X — <code>PaymentService</code> as <code>interface</code></em></p>
|
||
<p>If <code>OrderService</code> depends on a <code>PaymentService</code> interface, it doesn’t know anything about Stripe, PayPal, or any other payment provider. As long as these providers implement <code>PaymentService</code>, they can be used to handle payments — and <code>OrderService</code> won’t care which one is being used.</p>
|
||
<p><strong>Benefits:</strong></p>
|
||
<ol>
|
||
<li>If we replace <code>StripePaymentService</code> with <code>PayPalPaymentService</code>, the <code>OrderService</code> class is not affected.</li>
|
||
<li>We don’t need to modify or recompile <code>OrderService</code>.</li>
|
||
<li>We can test <code>OrderService</code> in isolation, without relying on the specific payment provider like Stripe.</li>
|
||
</ol>
|
||
<p>With this setup, we simply give <code>OrderService</code> a particular implementation of <code>PaymentService</code>. This is called <strong>dependency injection</strong> — we <em>inject</em> the dependency into a class.</p>
|
||
<p><img src="assets/dependency-injection.svg" alt="Dependency Injection example" loading="lazy" />
|
||
<em>Img. X — Dependency Injection example</em></p>
|
||
<p>Let’s see how it works in our project. Create <code>OrderService</code> at <code>src/main/java/tech/codejava/store/OrderService.java</code>:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> tech.codejava.store;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">OrderService</span> {
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">placeOrder</span>() {}
|
||
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:flex-col hx:rounded-lg hx:border hx:py-4 hx:px-4 hx:border-gray-200 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200">
|
||
<p class="hx:flex hx:items-center hx:font-medium"><svg height=16px class="hx:inline-block hx:align-middle hx:mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>Note</p>
|
||
|
||
<div class="hx:w-full hx:min-w-0 hx:leading-7">
|
||
<div class="hx:mt-6 hx:leading-7 hx:first:mt-0"><p>In a real project we would need to provide something like <code>Order order</code> to this method, but for teaching purposes we won’t do that.</p></div>
|
||
</div>
|
||
</div>
|
||
<p>Now create <code>StripePaymentService</code> in the same directory:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> tech.codejava.store;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">StripePaymentService</span> {
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">processPayment</span>(<span style="color:#66d9ef">double</span> amount) {
|
||
</span></span><span style="display:flex;"><span> System.<span style="color:#a6e22e">out</span>.<span style="color:#a6e22e">println</span>(<span style="color:#e6db74">"=== STRIPE ==="</span>);
|
||
</span></span><span style="display:flex;"><span> System.<span style="color:#a6e22e">out</span>.<span style="color:#a6e22e">println</span>(<span style="color:#e6db74">"amount: "</span> <span style="color:#f92672">+</span> amount);
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>Let’s implement <code>placeOrder</code> in <code>OrderService</code> using <code>StripePaymentService</code>:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> tech.codejava.store;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">OrderService</span> {
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">placeOrder</span>() {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> paymentService <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> StripePaymentService();
|
||
</span></span><span style="display:flex;"><span> paymentService.<span style="color:#a6e22e">processPayment</span>(10);
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:flex-col hx:rounded-lg hx:border hx:py-4 hx:px-4 hx:border-gray-200 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-purple-200 hx:bg-purple-100 hx:text-purple-900 hx:dark:border-purple-200/30 hx:dark:bg-purple-900/30 hx:dark:text-purple-200">
|
||
<p class="hx:flex hx:items-center hx:font-medium"><svg height=16px class="hx:inline-block hx:align-middle hx:mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>Important</p>
|
||
|
||
<div class="hx:w-full hx:min-w-0 hx:leading-7">
|
||
<div class="hx:mt-6 hx:leading-7 hx:first:mt-0"><p>This is our <em>before</em> setup — before we introduced the interface. In this implementation, <code>OrderService</code> is <strong>tightly coupled</strong> to <code>StripePaymentService</code>. We cannot test <code>OrderService</code> in isolation, and switching to another payment provider would require modifying <code>OrderService</code>.</p></div>
|
||
</div>
|
||
</div>
|
||
<p>Let’s fix this. Create a <code>PaymentService</code> interface in the same directory:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> tech.codejava.store;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">PaymentService</span> {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">processPayment</span>(<span style="color:#66d9ef">double</span> amount);
|
||
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>Modify <code>StripePaymentService</code> to implement <code>PaymentService</code>:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> tech.codejava.store;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">StripePaymentService</span> <span style="color:#66d9ef">implements</span> PaymentService {
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">@Override</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">processPayment</span>(<span style="color:#66d9ef">double</span> amount) {
|
||
</span></span><span style="display:flex;"><span> System.<span style="color:#a6e22e">out</span>.<span style="color:#a6e22e">println</span>(<span style="color:#e6db74">"=== STRIPE ==="</span>);
|
||
</span></span><span style="display:flex;"><span> System.<span style="color:#a6e22e">out</span>.<span style="color:#a6e22e">println</span>(<span style="color:#e6db74">"amount: "</span> <span style="color:#f92672">+</span> amount);
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>The recommended way to inject a dependency into a class is via its <strong>constructor</strong>. Let’s define one in <code>OrderService</code>:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> tech.codejava.store;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">OrderService</span> {
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">private</span> PaymentService paymentService;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#a6e22e">OrderService</span>(PaymentService paymentService) {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">paymentService</span> <span style="color:#f92672">=</span> paymentService;
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">placeOrder</span>() {
|
||
</span></span><span style="display:flex;"><span> paymentService.<span style="color:#a6e22e">processPayment</span>(10);
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>Now let’s see this in action. Modify <code>StoreApplication</code>:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> tech.codejava.store;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.springframework.boot.SpringApplication;
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.springframework.boot.autoconfigure.SpringBootApplication;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@SpringBootApplication</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">StoreApplication</span> {
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">main</span>(String<span style="color:#f92672">[]</span> args) {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// SpringApplication.run(StoreApplication.class, args);</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> orderService <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> OrderService(<span style="color:#66d9ef">new</span> StripePaymentService());
|
||
</span></span><span style="display:flex;"><span> orderService.<span style="color:#a6e22e">placeOrder</span>();
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>Running the application <em>(output intentionally reduced)</em>:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>...
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">===</span> STRIPE <span style="color:#f92672">===</span>
|
||
</span></span><span style="display:flex;"><span>amount: 10.0
|
||
</span></span><span style="display:flex;"><span>...</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>Now let’s create a <code>PayPalPaymentService</code> in the same directory:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> tech.codejava.store;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">PayPalPaymentService</span> <span style="color:#66d9ef">implements</span> PaymentService {
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">@Override</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">processPayment</span>(<span style="color:#66d9ef">double</span> amount) {
|
||
</span></span><span style="display:flex;"><span> System.<span style="color:#a6e22e">out</span>.<span style="color:#a6e22e">println</span>(<span style="color:#e6db74">"=== PayPal ==="</span>);
|
||
</span></span><span style="display:flex;"><span> System.<span style="color:#a6e22e">out</span>.<span style="color:#a6e22e">println</span>(<span style="color:#e6db74">"amount: "</span> <span style="color:#f92672">+</span> amount);
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>Now we can switch from <code>StripePaymentService</code> to <code>PayPalPaymentService</code> in <code>StoreApplication</code> — without touching <code>OrderService</code> at all:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> tech.codejava.store;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.springframework.boot.SpringApplication;
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.springframework.boot.autoconfigure.SpringBootApplication;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@SpringBootApplication</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">StoreApplication</span> {
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">main</span>(String<span style="color:#f92672">[]</span> args) {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// SpringApplication.run(StoreApplication.class, args);</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// var orderService = new OrderService(new StripePaymentService());</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> orderService <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> OrderService(<span style="color:#66d9ef">new</span> PayPalPaymentService());
|
||
</span></span><span style="display:flex;"><span> orderService.<span style="color:#a6e22e">placeOrder</span>();
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>...
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">===</span> PayPal <span style="color:#f92672">===</span>
|
||
</span></span><span style="display:flex;"><span>amount: 10.0
|
||
</span></span><span style="display:flex;"><span>...</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>Notice that we didn’t change <code>OrderService</code>. In <em>object-oriented programming</em> this is known as the <strong>Open/Closed Principle</strong>:</p>
|
||
<blockquote>
|
||
<p>A class should be open for extension and closed for modification.</p>
|
||
|
||
</blockquote>
|
||
<p>In other words: we should be able to add new functionality to a class without changing its existing code. This reduces the risk of introducing bugs and breaking other parts of the application.</p>
|
||
<hr>
|
||
<h2>Setter Injection<span class="hx:absolute hx:-mt-20" id="setter-injection"></span>
|
||
<a href="#setter-injection" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Another way to inject a dependency is via a <strong>setter</strong>. In <code>OrderService</code>, let’s define one:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> tech.codejava.store;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">OrderService</span> {
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">private</span> PaymentService paymentService;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">setPaymentService</span>(PaymentService paymentService) {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">paymentService</span> <span style="color:#f92672">=</span> paymentService;
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#a6e22e">OrderService</span>(PaymentService paymentService) {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">paymentService</span> <span style="color:#f92672">=</span> paymentService;
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">placeOrder</span>() {
|
||
</span></span><span style="display:flex;"><span> paymentService.<span style="color:#a6e22e">processPayment</span>(10);
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>We can use it like this in <code>StoreApplication</code>:</p>
|
||
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">
|
||
|
||
<div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">package</span> tech.codejava.store;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.springframework.boot.SpringApplication;
|
||
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> org.springframework.boot.autoconfigure.SpringBootApplication;
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@SpringBootApplication</span>
|
||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">StoreApplication</span> {
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">main</span>(String<span style="color:#f92672">[]</span> args) {
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// SpringApplication.run(StoreApplication.class, args);</span>
|
||
</span></span><span style="display:flex;"><span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#75715e">// var orderService = new OrderService(new StripePaymentService());</span>
|
||
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> orderService <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> OrderService(<span style="color:#66d9ef">new</span> PayPalPaymentService());
|
||
</span></span><span style="display:flex;"><span> orderService.<span style="color:#a6e22e">setPaymentService</span>(<span style="color:#66d9ef">new</span> PayPalPaymentService());
|
||
</span></span><span style="display:flex;"><span> orderService.<span style="color:#a6e22e">placeOrder</span>();
|
||
</span></span><span style="display:flex;"><span> }
|
||
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
|
||
<button
|
||
class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
|
||
title="Copy code"
|
||
>
|
||
<div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:flex-col hx:rounded-lg hx:border hx:py-4 hx:px-4 hx:border-gray-200 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-purple-200 hx:bg-purple-100 hx:text-purple-900 hx:dark:border-purple-200/30 hx:dark:bg-purple-900/30 hx:dark:text-purple-200">
|
||
<p class="hx:flex hx:items-center hx:font-medium"><svg height=16px class="hx:inline-block hx:align-middle hx:mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>Important</p>
|
||
|
||
<div class="hx:w-full hx:min-w-0 hx:leading-7">
|
||
<div class="hx:mt-6 hx:leading-7 hx:first:mt-0"><p>If you remove the constructor from <code>OrderService</code> and forget to call the setter, the application will crash with a <code>NullPointerException</code>. Use setter injection only for <strong>optional</strong> dependencies — ones that <code>OrderService</code> can function without.</p></div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
<div class="hx:mt-16"></div>
|
||
<div class="hx:mt-16"></div>
|
||
|
||
</main>
|
||
</article>
|
||
</div>
|
||
|
||
<footer class="hextra-footer hx:bg-gray-100 hx:pb-[env(safe-area-inset-bottom)] hx:dark:bg-neutral-900 hx:print:bg-transparent"><div class="hextra-custom-footer hextra-max-footer-width hx:pl-[max(env(safe-area-inset-left),1.5rem)] hx:pr-[max(env(safe-area-inset-right),1.5rem)] hx:text-gray-600 hx:dark:text-gray-400"></div><div
|
||
class="hextra-max-footer-width hx:mx-auto hx:flex hx:justify-center hx:py-12 hx:pl-[max(env(safe-area-inset-left),1.5rem)] hx:pr-[max(env(safe-area-inset-right),1.5rem)] hx:text-gray-600 hx:dark:text-gray-400 hx:md:justify-start"
|
||
>
|
||
<div class="hx:flex hx:w-full hx:flex-col hx:items-center hx:sm:items-start"><div class="hx:font-semibold"><a class="hx:flex hx:text-sm hx:items-center hx:gap-1 hx:text-current" target="_blank" rel="noopener noreferrer" title="Hextra GitHub Homepage" href="https://github.com/imfing/hextra">
|
||
<span>Powered by Hextra<svg height=1em class="hx:inline-block hx:ltr:ml-1 hx:rtl:mr-1 hx:align-[-2.5px]" viewBox="0 0 180 180" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path fill-rule="evenodd" clip-rule="evenodd" d="m 105.50024,22.224647 c -9.59169,-5.537563 -21.40871,-5.537563 -31.000093,0 L 39.054693,42.689119 C 29.463353,48.226675 23.55484,58.460531 23.55484,69.535642 v 40.928918 c 0,11.07542 5.908513,21.3092 15.499853,26.84652 l 35.445453,20.46446 c 9.591313,5.53732 21.408404,5.53732 31.000094,0 l 35.44507,-20.46446 c 9.59131,-5.53732 15.49985,-15.7711 15.49985,-26.84652 V 69.535642 c 0,-11.075111 -5.90854,-21.308967 -15.49985,-26.846523 z M 34.112797,85.737639 c -1.384445,2.397827 -1.384445,5.352099 0,7.749927 l 24.781554,42.922974 c 1.38437,2.39783 3.942853,3.87496 6.711592,3.87496 h 49.563107 c 2.76905,0 5.3273,-1.47713 6.71144,-3.87496 l 24.78194,-42.922974 c 1.38414,-2.397828 1.38414,-5.3521 0,-7.749927 L 121.88049,42.814746 c -1.38414,-2.397828 -3.94239,-3.874964 -6.71144,-3.874964 H 65.605944 c -2.768739,0 -5.327223,1.477059 -6.711592,3.874964 z" style="stroke-width:0.774993" /></svg></span>
|
||
</a></div></div>
|
||
</div></footer>
|
||
|
||
<script defer src="/js/main.js" integrity=""></script>
|
||
<script defer src="/js/flexsearch.9f5b5908f93ae86f1ecd4b043b799f580c2d1654e703dd9357d568ac41b2547a.js" integrity="sha256-n1tZCPk66G8ezUsEO3mfWAwtFlTnA92TV9VorEGyVHo=" crossorigin="anonymous"></script>
|
||
<script defer src="/en.search.js" integrity=""></script>
|
||
</body>
|
||
</html>
|