diff --git a/content/courses/prog-intro/lectures/assets/compilation-process-simplified.svg b/content/courses/prog-intro/lectures/assets/compilation-process-simplified.svg index 0286ca2..9cdda93 100644 --- a/content/courses/prog-intro/lectures/assets/compilation-process-simplified.svg +++ b/content/courses/prog-intro/lectures/assets/compilation-process-simplified.svg @@ -1 +1,4 @@ - + + + + \ No newline at end of file diff --git a/content/courses/prog-intro/lectures/assets/cpp-x86-64-compilation.svg b/content/courses/prog-intro/lectures/assets/cpp-x86-64-compilation.svg new file mode 100644 index 0000000..76db010 --- /dev/null +++ b/content/courses/prog-intro/lectures/assets/cpp-x86-64-compilation.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/content/courses/prog-intro/lectures/assets/java-code-compilation.svg b/content/courses/prog-intro/lectures/assets/java-code-compilation.svg new file mode 100644 index 0000000..fc26c64 --- /dev/null +++ b/content/courses/prog-intro/lectures/assets/java-code-compilation.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/content/courses/prog-intro/lectures/intro.md b/content/courses/prog-intro/lectures/intro.md index b561343..80580d1 100644 --- a/content/courses/prog-intro/lectures/intro.md +++ b/content/courses/prog-intro/lectures/intro.md @@ -25,3 +25,67 @@ Java consists of multiple main components. The first one being the **Java compil  *Img.2 - Simplified Compilation Process* + +The behaviour of the Java compiler is described by the [Java Language Specification](https://docs.oracle.com/javase/specs/) or JLS. + +Let's talk about compilers a little bit. For example if we will take *C++*. If we take C++ compiler for *x86-64* platform and *Windows* operating system, and launch the compiler on source code it will turn it directly into assembly code. + + +*Img. X -- C++ code compilation process under x86-64 architecture.* + +But what if I want to run my program on *Linux* instead of Windows. I will need to take a different compiler under different operating system and recompile my code using a new compiler. It's not very convenient. + +Java tries to protect us from that. By converting the *Java source code* into *Java byte code*. And then the *byte code* will be ran on the *Java virtual machine* which will run our program on the native processor. + + +*Img. X -- Java code compilation* + +This approach allows to change only **JVM** according to our platform (*x86_64, ARM, ...*) and operating system (*Windows, MacOS, GNU-Linux, ...*) while *byte code* stays the same. We can only write our code once, than compile it and run under everywhere. + +As the motto says: + +> Write once -- ~debug~ run everywhere. + + The third component of Java is the standart library which is included in the JVM. + +There are multiple redactions of Java-platforms: + +* Standart edition + - *For regular aplications* +* Enterprise edition + - *For server aplications* +* Micro-edition + - *For mobile aplications* + - *Isn't in use nowadays πͺ¦* +* Java Card + - *Sim- and smart-cards* + +There also were multiple versions of Java throughout its history. + + +- JDK 1.0 (Jan 1996) +- J2SE 1.2 (Dec 1998) + * *Collections Framework* +- J2SE 5.0 (Sep 2004) + * *Generics* +- Java SE 8 (Mar 2014) + * *Streams and Lambdas* +- Java SE 9 (Sep 2017) + * *Modules* +- Java SE 10 (Mar 2018) + * `var` +- Java 11 (Sep 2018) + * `jshell` +- Java 17 [LTS-old] (Sep 2021) + * *Previous stable version* + * *Many little changes* +- Java 21 [LTS] (Sep 2023) + * *Current stable version* +- Java 25 (Sep 2025) + * *Next version* + +Java comes in two parts: **JDK - Java Development Kit** and **JVM - Java Virtual Machine**. + +There is also a **JRE - Java Runtime Environment**. For example if we want to run our code somewhere on the server we don't need to compile it there because we have our byte code and we just need JRE to run it. + + diff --git a/public/courses/prog-intro/assets/compilation-process.svg b/public/courses/prog-intro/assets/compilation-process.svg new file mode 100644 index 0000000..650391b --- /dev/null +++ b/public/courses/prog-intro/assets/compilation-process.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/public/courses/prog-intro/lectures/assets/compilation-process-simplified.svg b/public/courses/prog-intro/lectures/assets/compilation-process-simplified.svg index 0286ca2..9cdda93 100644 --- a/public/courses/prog-intro/lectures/assets/compilation-process-simplified.svg +++ b/public/courses/prog-intro/lectures/assets/compilation-process-simplified.svg @@ -1 +1,4 @@ - + + + + \ No newline at end of file diff --git a/public/courses/prog-intro/lectures/assets/cpp-x86-64-compilation.svg b/public/courses/prog-intro/lectures/assets/cpp-x86-64-compilation.svg new file mode 100644 index 0000000..76db010 --- /dev/null +++ b/public/courses/prog-intro/lectures/assets/cpp-x86-64-compilation.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/public/courses/prog-intro/lectures/assets/java-code-compilation.svg b/public/courses/prog-intro/lectures/assets/java-code-compilation.svg new file mode 100644 index 0000000..fc26c64 --- /dev/null +++ b/public/courses/prog-intro/lectures/assets/java-code-compilation.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/public/courses/prog-intro/lectures/intro/index.html b/public/courses/prog-intro/lectures/intro/index.html index af583a4..730fb2e 100644 --- a/public/courses/prog-intro/lectures/intro/index.html +++ b/public/courses/prog-intro/lectures/intro/index.html @@ -53,7 +53,7 @@ What does Java consist of?Java consists of multiple main components. The first o Img. 1 - TIOBE Programming Community Index Also, Java has a lot of advantages for beginners such as: Itβs fairly easy It has a broad spectre of usage Server Desktop Mobile devices Smart-cards What does Java consist of?Java consists of multiple main components. The first one being the Java compiler. The process of converting human-readable text to machine code is called compilation."> - + Img.2 - Simplified Compilation Process
+The behaviour of the Java compiler is described by the Java Language Specification or JLS.
+Let’s talk about compilers a little bit. For example if we will take C++. If we take C++ compiler for x86-64 platform and Windows operating system, and launch the compiler on source code it will turn it directly into assembly code.
+
+
+Img. X – C++ code compilation process under x86-64 architecture.
But what if I want to run my program on Linux instead of Windows. I will need to take a different compiler under different operating system and recompile my code using a new compiler. It’s not very convenient.
+Java tries to protect us from that. By converting the Java source code into Java byte code. And then the byte code will be ran on the Java virtual machine which will run our program on the native processor.
+
+
+Img. X – Java code compilation
This approach allows to change only JVM according to our platform (x86_64, ARM, …) and operating system (Windows, MacOS, GNU-Linux, …) while byte code stays the same. We can only write our code once, than compile it and run under everywhere.
+As the motto says:
+++Write once –
+ +debugrun everywhere.
The third component of Java is the standart library which is included in the JVM.
+There are multiple redactions of Java-platforms:
+There also were multiple versions of Java throughout its history.
+varjshellJava comes in two parts: JDK - Java Development Kit and JVM - Java Virtual Machine.
+There is also a JRE - Java Runtime Environment. For example if we want to run our code somewhere on the server we don’t need to compile it there because we have our byte code and we just need JRE to run it.
diff --git a/public/en.search-data.json b/public/en.search-data.json index 37fc9db..f38066d 100644 --- a/public/en.search-data.json +++ b/public/en.search-data.json @@ -1 +1 @@ -{"/courses/prog-intro/lectures/intro/":{"data":{"what-does-java-consist-of#What does Java consist of?":"Java consists of multiple main components. The first one being the Java compiler. The process of converting human-readable text to machine code is called compilation.\nImg.2 - Simplified Compilation Process","why-do-we-choose-java#Why do we choose Java?":"Why do we choose Java?According to TIOBE Programming Community Index Java is one of the most demanded languages in the programming field.\nImg. 1 - TIOBE Programming Community Index\nAlso, Java has a lot of advantages for beginners such as:\nItβs fairly easy It has a broad spectre of usage Server Desktop Mobile devices Smart-cards"},"title":"Lecture 1. Introduction"},"/courses/spring-boot/":{"data":{"configuring-application-properties#Configuring Application Properties":"Letβs take a look at our application.properties file located at src/main/resources/application.properties.\nspring.application.name=store To use this property in our code we can use the @Value annotation.\nLetβs change our HomeController class so it prints the name of our application.\npackage us.fymio.store; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class HomeController { @Value(\"${spring.application.name}\") private String appName; @RequestMapping(\"/\") // this represents the root of our website public String index() { System.out.println(\"application name = \" + appName); return \"index.html\"; // this returns the view } } And as we can see after running our application there is a store printed out in the terminal.\n... 2026-02-19T15:32:37.507+03:00 INFO 41536 --- [store] [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2026-02-19T15:32:37.509+03:00 INFO 41536 --- [store] [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms application name = store ...","controllers#Controllers":"Spring MVC stands for Model View Controller.\nModel 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.\nView is what the user sees. Itβs the HTML, CSS or JavaScript thatβs rendered in the browser. In Spring MVC views can be static files or dynamically generated.\nController 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.\nLetβs add a new java class called HomeController. It will be located at src/main/java/us/fymio/store/HomeController.java.\npackage us.fymio.store; public class HomeController {} To make this a controller we have to decorate it with the controller annotation. And import the Controller from org.springframework.stereotype package.\npackage us.fymio.store; import org.springframework.stereotype.Controller; @Controller public class HomeController {} Letβs now add an index method. When we send a request to the root of our website we want this method to be called. Also we need to add another special annotation to this method.\npackage us.fymio.store; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class HomeController { @RequestMapping(\"/\") // this represents the root of our website public String index() { return \"index.html\"; // this returns the view } } Now we need to create this view. We add the index.html at src/main/resources/static/index.html. For now letβs just print βHello world!β.\n\u003c!doctype html\u003e \u003chtml lang=\"en\"\u003e \u003chead\u003e \u003cmeta charset=\"UTF-8\" /\u003e \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /\u003e \u003ctitle\u003eView\u003c/title\u003e \u003c/head\u003e \u003cbody\u003e \u003ch1\u003eHello world!\u003c/h1\u003e \u003c/body\u003e \u003c/html\u003e Now letβs build our application using mvn spring-boot:run.\nAs we can see from the logs:\n2026-02-19T14:55:23.948+03:00 INFO 36752 --- [store] [ main] o.s.boot.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) It means that our app is up and running at localhost:8080.\nImg. 7 β Our app is up and running!","dependency-injection#Dependency injection":"Imagine we are building an E-Commerce application that handles placing orders. When the order is placed, the customerβs payment needs to be processed so order service depends on a payment service like stripe payment service. In this case we can say that order service is dependent or coupled to stripe payment service.\nImg. 8 β Depends On/Coupled To relation.\nLetβs talk about issues that arise when one class is tightly coupled or dependent on another.\nThe first problem is the OrderService can only use StripePaymentService. If tomorrow we decide to switch to a different payment provider like PayPal, we would have to modify the OrderService code and once we change the order service class it has to be recompiled and retested which could impact other classes that depend on OrderService.\nThe second problem is that we cannot test OrderService in isolation because OrderService is tightly coupled with StripePaymentService and we canβt test its logic separately from StripePaymentService.\nThe problem here isnβt that OrderService depends on StripePaymentService. Dependencies are normal in any application. The issue here is about how the dependency is created and managed.\nLet me give you an analogy. Think of a restaurant. A restaurant business needs a chef. There is a dependency between the restaurant and the chef. If the current chef becomes unavailable the restaurant can hire another chef. This kind of dependency is totally normal.\nImg. X β Restaurant β Chef dependency (Normal)\nWhat if we replace chef with John. That means that our restaurant is now dependent on John β specific chef. What if John becomes unavailable. We canβt replace him with someone else and the restaurant will be in trouble. This is an example of tight or bad coupling.\nImg. X β Restaurant β John dependency (Bad coupling)\nWe donβt want OrderService to be tightly coupled to a specific payment service like Stripe. Thatβs like restaurant being dependent on a specific chef instead we want OrderService to depend on a PaymentService which could be Stripe, PayPal or any other provider. To achive this we can use the interface to decouple OrderService from StripePaymentService.\nImg. X β PaymentService as interface","dependency-management#Dependency Management":"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 Tomcat, we need libraries for handling web requests building APIs, processing JSON data, logging and so on.\nIn spring boot applications instead of adding multiple individual libraries we can use a starter dependency.\nImg. 5 β Spring Boot Starter Web\nTo use this dependency we just need to copy the code below to our pom.xml file.\norg.springframework.boot spring-boot-starter-web 4.1.0-M1 So the dependencies section would look like this\norg.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-web Notice, that I commented out the version of our dependency. Thatβs because itβs a better practice to let Spring Boot decide what version of the dependency to use.","initialize-spring-boot-project#Initialize Spring Boot Project":"To initialize a new spring boot project you can go to start.spring.io and select options that suits you.\nImg. 3 β Spring Boot options\nAfter unpacking the zip arvhive we have this template project.\n. βββ HELP.md βββ mvnw βββ mvnw.cmd βββ pom.xml βββ src β βββ main β β βββ java β β β βββ us β β β βββ fymio β β β βββ store β β β βββ StoreApplication.java β β βββ resources β β βββ application.properties β βββ test β βββ java β βββ us β βββ fymio β βββ store β βββ StoreApplicationTests.java βββ target βββ classes β βββ application.properties β βββ us β βββ fymio β βββ store β βββ StoreApplication.class βββ generated-sources β βββ annotations βββ generated-test-sources β βββ test-annotations βββ maven-status β βββ maven-compiler-plugin β βββ compile β β βββ default-compile β β βββ createdFiles.lst β β βββ inputFiles.lst β βββ testCompile β βββ default-testCompile β βββ createdFiles.lst β βββ inputFiles.lst βββ surefire-reports β βββ TEST-us.fymio.store.StoreApplicationTests.xml β βββ us.fymio.store.StoreApplicationTests.txt βββ test-classes βββ us βββ fymio βββ store βββ StoreApplicationTests.class The βheartβ of our project is the file named pom.xml:\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\" ?\u003e","prerequisites#Prerequisites":"Prerequisites Solid understanding of Java Object-oriented programming Classes, methods and interfaces Basic understanding of databases Tables, primary keys, foreign keys, relationships, etc. Write basic SQL statements","what-is-a-spring-framework#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 few different layers.\nImg. 1 β Spring layers\nLayer Purpose Core Handling dependency injection, managing objects Web Building web applications Data Working with databases AOP Aspect oriented programming Test Testing spring components While the spring framework is powerfull, 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 Spring Boot comes in.\nYou can think of spring boot as a layer on top of the spring framework, that takes care of all of the setup.\nSring Boot siplifies Spring development by providing sensible defaults and ready-to-use features.\nBy the way, the spring framework is just one part of a larger family of projects in the spring ecosystem.\nImg. 2 β Spring ecosystem\nModule Name Purpose Spring Data Simplifying database access Spring Security Adding authentication and authorization Spring Batch Batch processing Spring Cloud Building microservices and distributed systems Spring Integration Symplifying messaging and integration between systems"},"title":"_index"}} \ No newline at end of file +{"/courses/prog-intro/lectures/intro/":{"data":{"what-does-java-consist-of#What does Java consist of?":"Java consists of multiple main components. The first one being the Java compiler. The process of converting human-readable text to machine code is called compilation.\nImg.2 - Simplified Compilation Process","why-do-we-choose-java#Why do we choose Java?":"Why do we choose Java?According to TIOBE Programming Community Index Java is one of the most demanded languages in the programming field.\nImg. 1 - TIOBE Programming Community Index\nAlso, Java has a lot of advantages for beginners such as:\nItβs fairly easy It has a broad spectre of usage Server Desktop Mobile devices Smart-cards"},"title":"Lecture 1. Introduction"},"/courses/spring-boot/":{"data":{"configuring-application-properties#Configuring Application Properties":"Letβs take a look at src/main/resources/application.properties:\nspring.application.name=store To use this property in our code, we can use the @Value annotation. Letβs update HomeController to print the application name:\npackage tech.codejava.store; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class HomeController { @Value(\"${spring.application.name}\") private String appName; @RequestMapping(\"/\") // this represents the root of our website public String index() { System.out.println(\"application name = \" + appName); return \"index.html\"; // this returns the view } } After running the application, we can see store printed in the terminal:\n... 2026-02-19T15:32:37.507+03:00 INFO 41536 --- [store] [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2026-02-19T15:32:37.509+03:00 INFO 41536 --- [store] [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms application name = store ...","controllers#Controllers":"Spring MVC stands for Model View Controller.\nModel 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. View 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. Controller 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. Letβs add a new Java class called HomeController at src/main/java/tech/codejava/store/HomeController.java:\npackage tech.codejava.store; public class HomeController {} To make this a controller, decorate it with the @Controller annotation:\npackage tech.codejava.store; import org.springframework.stereotype.Controller; @Controller public class HomeController {} Now letβs add an index method. When we send a request to the root of our website, we want this method to be called:\npackage tech.codejava.store; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class HomeController { @RequestMapping(\"/\") // this represents the root of our website public String index() { return \"index.html\"; // this returns the view } } Now we need to create the view. Add index.html at src/main/resources/static/index.html:\n\u003c!doctype html\u003e \u003chtml lang=\"en\"\u003e \u003chead\u003e \u003cmeta charset=\"UTF-8\" /\u003e \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /\u003e \u003ctitle\u003eView\u003c/title\u003e \u003c/head\u003e \u003cbody\u003e \u003ch1\u003eHello world!\u003c/h1\u003e \u003c/body\u003e \u003c/html\u003e Letβs build and run our application using mvn spring-boot:run. From the logs:\n2026-02-19T14:55:23.948+03:00 INFO 36752 --- [store] [ main] o.s.boot.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) Our app is up and running at localhost:8080.\nImg. 7 β Our app is up and running!","dependency-injection#Dependency Injection":"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 OrderService depends on a payment service like StripePaymentService. We can say that OrderService is dependent on (or coupled to) StripePaymentService.\nImg. 8 β Depends On/Coupled To relation\nLetβs talk about the issues that arise when one class is tightly coupled to another.\nInflexibility β OrderService can only use StripePaymentService. If tomorrow we decide to switch to a different payment provider like PayPal, we would have to modify OrderService. Once we change it, it has to be recompiled and retested, which could impact other classes that depend on it. Untestability β We cannot test OrderService in isolation, because OrderService is tightly coupled with StripePaymentService and we canβt test its logic separately from it. Note\nThe problem here isnβt that OrderService depends on StripePaymentService β dependencies are normal in any application. The issue is about how the dependency is created and managed.\nAnalogy: 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.\nImg. X β Restaurant β Chef dependency (Normal)\nNow what if we replace βchefβ with a specific person: John? Our restaurant is now dependent on John specifically. If John becomes unavailable, we canβt replace him β the restaurant is in trouble. This is an example of tight or bad coupling.\nImg. X β Restaurant β John dependency (Bad coupling)\nWe donβt want OrderService to be tightly coupled to a specific payment service like Stripe. Instead, we want it to depend on a PaymentService interface, which could be Stripe, PayPal, or any other provider. To achieve this we can use the interface to decouple OrderService from StripePaymentService.\nImg. X β PaymentService as interface\nIf OrderService depends on a PaymentService interface, it doesnβt know anything about Stripe, PayPal, or any other payment provider. As long as these providers implement PaymentService, they can be used to handle payments β and OrderService wonβt care which one is being used.\nBenefits:\nIf we replace StripePaymentService with PayPalPaymentService, the OrderService class is not affected. We donβt need to modify or recompile OrderService. We can test OrderService in isolation, without relying on the specific payment provider like Stripe. With this setup, we simply give OrderService a particular implementation of PaymentService. This is called dependency injection β we inject the dependency into a class.\nImg. X β Dependency Injection example\nLetβs see how it works in our project. Create OrderService at src/main/java/tech/codejava/store/OrderService.java:\npackage tech.codejava.store; public class OrderService { public void placeOrder() {} } Note\nIn a real project we would need to provide something like Order order to this method, but for teaching purposes we wonβt do that.\nNow create StripePaymentService in the same directory:\npackage tech.codejava.store; public class StripePaymentService { public void processPayment(double amount) { System.out.println(\"=== STRIPE ===\"); System.out.println(\"amount: \" + amount); } } Letβs implement placeOrder in OrderService using StripePaymentService:\npackage tech.codejava.store; public class OrderService { public void placeOrder() { var paymentService = new StripePaymentService(); paymentService.processPayment(10); } } Important\nThis is our before setup β before we introduced the interface. In this implementation, OrderService is tightly coupled to StripePaymentService. We cannot test OrderService in isolation, and switching to another payment provider would require modifying OrderService.\nLetβs fix this. Create a PaymentService interface in the same directory:\npackage tech.codejava.store; public interface PaymentService { void processPayment(double amount); } Modify StripePaymentService to implement PaymentService:\npackage tech.codejava.store; public class StripePaymentService implements PaymentService { @Override public void processPayment(double amount) { System.out.println(\"=== STRIPE ===\"); System.out.println(\"amount: \" + amount); } } The recommended way to inject a dependency into a class is via its constructor. Letβs define one in OrderService:\npackage tech.codejava.store; public class OrderService { private PaymentService paymentService; public OrderService(PaymentService paymentService) { this.paymentService = paymentService; } public void placeOrder() { paymentService.processPayment(10); } } Now letβs see this in action. Modify StoreApplication:\npackage tech.codejava.store; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class StoreApplication { public static void main(String[] args) { // SpringApplication.run(StoreApplication.class, args); var orderService = new OrderService(new StripePaymentService()); orderService.placeOrder(); } } Running the application (output intentionally reduced):\n... === STRIPE === amount: 10.0 ... Now letβs create a PayPalPaymentService in the same directory:\npackage tech.codejava.store; public class PayPalPaymentService implements PaymentService { @Override public void processPayment(double amount) { System.out.println(\"=== PayPal ===\"); System.out.println(\"amount: \" + amount); } } Now we can switch from StripePaymentService to PayPalPaymentService in StoreApplication β without touching OrderService at all:\npackage tech.codejava.store; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class StoreApplication { public static void main(String[] args) { // SpringApplication.run(StoreApplication.class, args); // var orderService = new OrderService(new StripePaymentService()); var orderService = new OrderService(new PayPalPaymentService()); orderService.placeOrder(); } } ... === PayPal === amount: 10.0 ... Notice that we didnβt change OrderService. In object-oriented programming this is known as the Open/Closed Principle:\nA class should be open for extension and closed for modification.\nIn 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.","dependency-management#Dependency Management":"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 Tomcat, libraries for handling web requests, building APIs, processing JSON data, logging and so on.\nIn Spring Boot applications, instead of adding multiple individual libraries, we can use a starter dependency.\nImg. 5 β Spring Boot Starter Web\nTo use this dependency, copy the following into your pom.xml:\norg.springframework.boot spring-boot-starter-web 4.1.0-M1 So the dependencies section would look like this:\norg.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-web Important\nNotice 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.","initialize-spring-boot-project#Initialize Spring Boot Project":"To initialize a new Spring Boot project, go to start.spring.io and select the options that suit you.\nImg. 3 β Spring Boot options\nAfter unpacking the zip archive, youβll have this template project:\n. βββ HELP.md βββ mvnw βββ mvnw.cmd βββ pom.xml βββ src β βββ main β β βββ java β β β βββ tech β β β βββ codejava β β β βββ store β β β βββ StoreApplication.java β β βββ resources β β βββ application.properties β βββ test β βββ java β βββ tech β βββ codejava β βββ store β βββ StoreApplicationTests.java βββ target βββ classes β βββ application.properties β βββ tech β βββ codejava β βββ store β βββ StoreApplication.class βββ generated-sources β βββ annotations βββ generated-test-sources β βββ test-annotations βββ maven-status β βββ maven-compiler-plugin β βββ compile β β βββ default-compile β β βββ createdFiles.lst β β βββ inputFiles.lst β βββ testCompile β βββ default-testCompile β βββ createdFiles.lst β βββ inputFiles.lst βββ surefire-reports β βββ TEST-tech.codejava.store.StoreApplicationTests.xml β βββ tech.codejava.store.StoreApplicationTests.txt βββ test-classes βββ tech βββ codejava βββ store βββ StoreApplicationTests.class The βheartβ of our project is pom.xml:\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\" ?\u003e","prerequisites#Prerequisites":"PrerequisitesBefore diving in, make sure youβre comfortable with the following:\nJava β 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","setter-injection#Setter Injection":"Another way to inject a dependency is via a setter. In OrderService, letβs define one:\npackage tech.codejava.store; public class OrderService { private PaymentService paymentService; public void setPaymentService(PaymentService paymentService) { this.paymentService = paymentService; } public OrderService(PaymentService paymentService) { this.paymentService = paymentService; } public void placeOrder() { paymentService.processPayment(10); } } We can use it like this in StoreApplication:\npackage tech.codejava.store; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class StoreApplication { public static void main(String[] args) { // SpringApplication.run(StoreApplication.class, args); // var orderService = new OrderService(new StripePaymentService()); var orderService = new OrderService(new PayPalPaymentService()); orderService.setPaymentService(new PayPalPaymentService()); orderService.placeOrder(); } } Important\nIf you remove the constructor from OrderService and forget to call the setter, the application will crash with a NullPointerException. Use setter injection only for optional dependencies β ones that OrderService can function without.","what-is-a-spring-framework#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.\nImg. 1 β Spring layers\nLayer Purpose Core Handling dependency injection, managing objects Web Building web applications Data Working with databases AOP Aspect oriented programming Test Testing spring components 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 Spring Boot comes in.\nNote\nYou can think of Spring Boot as a layer on top of the Spring Framework that takes care of all of the setup. Spring Boot simplifies Spring development by providing sensible defaults and ready-to-use features.\nBy the way, the Spring Framework is just one part of a larger family of projects in the Spring ecosystem.\nImg. 2 β Spring ecosystem\nModule Name Purpose Spring Data Simplifying database access Spring Security Adding authentication and authorization Spring Batch Batch processing Spring Cloud Building microservices and distributed systems Spring Integration Simplifying messaging and integration between systems"},"title":"_index"}} \ No newline at end of file