From 56d8b18948eaf8a3f1134953448b848ebabfe0ca Mon Sep 17 00:00:00 2001 From: Kelsey Sterner Date: Wed, 21 Aug 2024 17:20:42 -0400 Subject: [PATCH 01/11] Rough Spring Article Start --- backend/spring/README.md | 339 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 339 insertions(+) create mode 100644 backend/spring/README.md diff --git a/backend/spring/README.md b/backend/spring/README.md new file mode 100644 index 0000000..973c669 --- /dev/null +++ b/backend/spring/README.md @@ -0,0 +1,339 @@ +# Gen Topics +- IoC containers (Inversion of Control) +- Data access framework +- Dependency injections + - Injecting object dependencies + +- Maven + - Maven Project, Maven archetypes + - Group ID / Artifact ID + - pom.xml file + - Maven repository for xml dependencies + +Achieving dependency injections through configuration +- XML configuration (using Component) + ex. + App.java + public class App { + public static void main(String[] args) { + ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml") // Your own xml file and file name + + Vehicle obj = (Vehicle)context.getBean("vehicle"); + obj.drive(); + } + } + spring.xml (in src) + + + + + + +- Annotation based configuration * (Components, Autowired) + ex. + App.java + public class App { + public static void main(String[] args) { + ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml") // Your own xml file and file name + + Vehicle obj = (Vehicle)context.getBean("car"); + obj.drive(); + } + } + spring.xml (in src) + + + + + + + Car.java + package com.navin.Telusko; + @Component // <- important + public class Car implements Vehicle { + public void drive() { + System.out.println("driving"); + } + } + +- Combo Annotation & Xml w/ Bean property tags + ex. + App.java + public class App { + public static void main(String[] args) { + ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml") // Your own xml file and file name + + Tire t = (Tire) context.getBean("tire"); + System.out.println(t); + } + } + spring.xml (in src) + + + + + // Xml formatting to accomodate tire + + + + + + Car.java + package com.navin.Telusko; + + @Component // <- important + public class Car implements Vehicle { + public void drive() { + System.out.println("driving"); + } + } + + Tire.java + package com.navin.Telusko; + + public class Tire { + private String brand; + + public String getBrand() { + return brand; + } + + public void setBrand(String brand) { + this.brand= brand; + } + + @Override + public String toString() { + return "Tire [brand=" + brand + "]"; + } + } + +- Constructor Injection (Still mixed Annotation and Xml Config) & Autowired + ex. + App.java + public class App { + public static void main(String[] args) { + ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml") // Your own xml file and file name + + Car obj = (Car)context.getBean("car"); + obj.drive(); + } + } + spring.xml (in src) + + + + + // Xml formatting to accomodate tire + + + + + + Car.java + package com.navin.Telusko; + + @Component // <- important + public class Car implements Vehicle { + + @Autowired + private Tire tire; + + public Tire getTire() { + return tire + } + + public void setTire(Tire tire) { + this.tire = tire; + } + + public void drive() { + System.out.println("car" + tire); + } + } + + Tire.java + package com.navin.Telusko; + + @Component + public class Tire { + private String brand; + + public Tire(String brand) { + super(); + this.brand = brand; + } + + public String getBrand() { + return brand; + } + + public void setBrand(String brand) { + this.brand= brand; + } + + @Override + public String toString() { + return "Tire [brand=" + brand + "]"; + } + } + +- Annotation Confirguation using Maven (New Example) + 1. Create Maven project (Quick start maven archetype) + 2. Add dependencies to pom.xml from Maven Repository + - Spring context copy and paste + Samsung.java + package com.telusko.SpringAnno; + + + public class Samsung { + + @Autowired // checks by type + MobileProcessor cpu; + + public MobileProcessor getCpu() { + return cpu; + } + + public void setCpu(MobileProcessor cpu) { + this.cpu = cpu; + } + + public void config() { + System.out.println("Octa Core, 4 gb Ram, 12MP camera"); + cpu.process(); + } + } + + App.java + package com.telusko.SpringAnno; + + public class App { + public static void main(String[] args) { + ApplicationContext factory = new AnnotationConfigApplicationContext(AppConfig.class); + + Samsung s7 = factory.getBean(Samsung.class); + s7.config(); + } + } + + AppConfig.java + package com.telusko.SpringAnno; + + // import statements auto inserted here + + @Configuration + public class AppConfig { + + @Bean + public Samsung getPhone() { + return new Samsung(); + } + @Bean + public MobileProcessor getProcessor() { + return new Snapdragon(); + } + + } + + MobileProcessor.java + package com.telusko.SpringAnno; + + public interface MobileProcessor { + void process(); + } + + Snapdragon.java + package com.telusko.SpringAnno; + + public class Snapdragon implements MobileProcessor { + public void process() { + System.out.println("Word's best CPU"); + } + } +- Annotation Component (AutoWird Primary Qualifier) + 1. Add Component tags to Samsung and Snapdragon + 2. Add ComponentScan to AppConfig to find components (it looks by type) + - defaults to class name decapitalized (Samsung->samsung) + - With multiple components, you can define a primary (@Primary) or a qualifier (@Qualifier("id")) + - + Samsung.java + package com.telusko.SpringAnno; + + @Component + public class Samsung { + + @Autowired // checks by type + @Qualifier("snapdragon") + MobileProcessor cpu; + + public MobileProcessor getCpu() { + return cpu; + } + + public void setCpu(MobileProcessor cpu) { + this.cpu = cpu; + } + + public void config() { + System.out.println("Octa Core, 4 gb Ram, 12MP camera"); + cpu.process(); + } + } + + App.java + package com.telusko.SpringAnno; + + // Spring Core Annotations + public class App { + public static void main(String[] args) { + ApplicationContext factory = new AnnotationConfigApplicationContext(AppConfig.class); + + Samsung s7 = factory.getBean(Samsung.class); + s7.config(); + } + } + + AppConfig.java + package com.telusko.SpringAnno; + + // import statements auto inserted here + + @Configuration + @ComponentScan(basePackages="com.telusko.SpringAnno") + public class AppConfig { + + } + + MobileProcessor.java + package com.telusko.SpringAnno; + + public interface MobileProcessor { + void process(); + } + + Snapdragon.java + package com.telusko.SpringAnno; + + // importing Component + + @Component + @Primary + public class Snapdragon implements MobileProcessor { + public void process() { + System.out.println("Word's best CPU"); + } + } + + MediaTek.java + package com.telusko.SpringAnno; + + // importing Component + + @Component + public class MediaTek implements MobileProcessor { + public void process() { + System.out.println("2nd best CPU"); + } + } + From be7652985e9aee643703fa0d61287d84698c668f Mon Sep 17 00:00:00 2001 From: Kelsey Sterner Date: Wed, 21 Aug 2024 21:20:57 -0400 Subject: [PATCH 02/11] Update README.md --- backend/spring/README.md | 87 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/backend/spring/README.md b/backend/spring/README.md index 973c669..edc827b 100644 --- a/backend/spring/README.md +++ b/backend/spring/README.md @@ -1,3 +1,36 @@ +## IoC +Inversion of control (IoC) is a **principle** where the control of creating objects (in this case) is given to something (Ex. Spring Framework) other than the developer. In Spring this is done through a **design pattern** called dependency injection + +## DI +Dependency injection in Spring +- Constructor injection +- Setter injection +- Field injection (Not recommended) + - Loose coupling (code for interfaces) + +## Coupling +Coupling: How much work is involved in changing something? +- Tightly coupled: Engine to a car, Computer to your house (harder to move) +- Loosely coupled: Tire to a car, laptop to your house (can take anywhere) +* In software, loosely coupled is often better as code is always changing and iterating to better versions + +Tightly coupled code: +SuperMario mario = new SuperMario(); +GameRunner runner = new GameRunner(mario); +// GameRunner can only run mario games, and code needs to be changed within GamerRunner to run others + +Loosely coupled code: +* GamingConsole is an interface +GameingConsole game1 = new SuperMario(); +GameingConsole game2 = new PacMan(); +GameRunner runner = new GameRunner(game1); +GameRunner runner = new GameRunner(game2); +// Because all games must implement the GameingConsole interface, GameRunner can accept any GameingConsole object in the constructor + +Tutorial References (Highly recommend watching!) +- https://www.youtube.com/watch?v=f6DHAgL7FWc (More beginner friendly, decent examples) +- https://www.youtube.com/watch?v=If1Lw4pLLEo (Fast, comprehensive, good examples) + # Gen Topics - IoC containers (Inversion of Control) - Data access framework @@ -337,3 +370,57 @@ Achieving dependency injections through configuration } } +### Another Example of implementing Spring -> Hello World Application + +App.java +package ... + +imports + +public class App { + public static void main(String[] args) { + // 1: Launch a Spring Context + + var context = new AnnotationConfigApplicationContext(AppConfig.class) + + // 2: Configure the things we want Spring to manage - @Configuration + System.out.println(context.getBean("name")); // Returns "Jenn" + System.out.println(context.getBean("address")) // Returns error, we renamed address -> address2 + + System.out.println(context.getBean(Address.class)) // Can use type of Bean + + + } +} + +AppConfig.java +package ... + +imports + +record Person (String name, int age) {}; +record Address (String firstLine, String city) {}; + +public class AppConfig { + + @Bean + public String name() { + return "Jenn"; + } + @Bean + public int age() { + return 15; + } + + @Bean + public Person person() { + var person = new Person("Jack", 18); + return person; + } + + @Bean(name = "address2") + public Address address() { + return new Address("Baker Street", "London"); + } + +} \ No newline at end of file From fe25d1f8bfe95094403ecd8fe9f5646a5a8bc524 Mon Sep 17 00:00:00 2001 From: Kelsey Sterner Date: Wed, 21 Aug 2024 21:24:13 -0400 Subject: [PATCH 03/11] Update README.md --- backend/spring/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/spring/README.md b/backend/spring/README.md index edc827b..bada7e6 100644 --- a/backend/spring/README.md +++ b/backend/spring/README.md @@ -29,7 +29,7 @@ GameRunner runner = new GameRunner(game2); Tutorial References (Highly recommend watching!) - https://www.youtube.com/watch?v=f6DHAgL7FWc (More beginner friendly, decent examples) -- https://www.youtube.com/watch?v=If1Lw4pLLEo (Fast, comprehensive, good examples) +- https://www.youtube.com/watch?v=If1Lw4pLLEo (Fast, comprehensive, good examples) [Also has a more recentt playlist making an example project with Spring and Springboot] # Gen Topics - IoC containers (Inversion of Control) From 78fba03c536c220538152ef44c489eef6c113e84 Mon Sep 17 00:00:00 2001 From: Kelsey Sterner Date: Wed, 21 Aug 2024 22:18:06 -0400 Subject: [PATCH 04/11] Update README.md --- backend/spring/README.md | 76 +++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 25 deletions(-) diff --git a/backend/spring/README.md b/backend/spring/README.md index bada7e6..bd5ce6e 100644 --- a/backend/spring/README.md +++ b/backend/spring/README.md @@ -1,3 +1,9 @@ +# Spring Overview +This overview was created from notes following 2 youtube tutorials (links provided later in the article) and Spring tutorial articles + +## Prerequisites +- Must have a solid understanding of Java and OOP (particularly interfaces) + ## IoC Inversion of control (IoC) is a **principle** where the control of creating objects (in this case) is given to something (Ex. Spring Framework) other than the developer. In Spring this is done through a **design pattern** called dependency injection @@ -27,9 +33,26 @@ GameRunner runner = new GameRunner(game1); GameRunner runner = new GameRunner(game2); // Because all games must implement the GameingConsole interface, GameRunner can accept any GameingConsole object in the constructor +## Spring Container/Context (IoC Container) +(is within JVM [Java Virutal Machine]) +- Manages Spring beans & their lifecycle +- Bean Factory: Basic Spring Container (Not really used) +- **Application Context**: Advanced Spring Container w/ enterprise-specific features + - Good for web apps, web services, REST API, and microservices + - Easy internationalization + - Easy integration with Spring AOP (Aspect oriented programming) + +### POJO: Plain Old Java Object +- No constraints +- Any Java Object is a POJO + +### Spring Bean: Any Java Object managed by Spring +- Spring uses IoC Container (Ex. Application Context) to manage these objects + Tutorial References (Highly recommend watching!) -- https://www.youtube.com/watch?v=f6DHAgL7FWc (More beginner friendly, decent examples) +- https://www.youtube.com/watch?v=f6DHAgL7FWc (More beginner friendly, decent examples, not as concise) - https://www.youtube.com/watch?v=If1Lw4pLLEo (Fast, comprehensive, good examples) [Also has a more recentt playlist making an example project with Spring and Springboot] +I watched the 2nd one first, and put the 1st on 1.5x to review. # Gen Topics - IoC containers (Inversion of Control) @@ -43,8 +66,8 @@ Tutorial References (Highly recommend watching!) - pom.xml file - Maven repository for xml dependencies -Achieving dependency injections through configuration -- XML configuration (using Component) +### Achieving dependency injections through configuration +#### XML configuration (using Component) ex. App.java public class App { @@ -62,7 +85,7 @@ Achieving dependency injections through configuration -- Annotation based configuration * (Components, Autowired) +#### Annotation based configuration * (Components, Autowired) ex. App.java public class App { @@ -89,7 +112,7 @@ Achieving dependency injections through configuration } } -- Combo Annotation & Xml w/ Bean property tags +#### Combo Annotation & Xml w/ Bean property tags ex. App.java public class App { @@ -141,7 +164,7 @@ Achieving dependency injections through configuration } } -- Constructor Injection (Still mixed Annotation and Xml Config) & Autowired +#### Constructor Injection (Still mixed Annotation and Xml Config) & Autowired ex. App.java public class App { @@ -211,7 +234,7 @@ Achieving dependency injections through configuration } } -- Annotation Confirguation using Maven (New Example) +#### Annotation Confirguation using Maven (New Example) 1. Create Maven project (Quick start maven archetype) 2. Add dependencies to pom.xml from Maven Repository - Spring context copy and paste @@ -284,7 +307,7 @@ Achieving dependency injections through configuration System.out.println("Word's best CPU"); } } -- Annotation Component (AutoWird Primary Qualifier) +#### Annotation Component (AutoWird Primary Qualifier) 1. Add Component tags to Samsung and Snapdragon 2. Add ComponentScan to AppConfig to find components (it looks by type) - defaults to class name decapitalized (Samsung->samsung) @@ -380,10 +403,15 @@ imports public class App { public static void main(String[] args) { // 1: Launch a Spring Context + try(var context = new AnnotationConfigApplicationContext(AppConfig.class)) { + // 2: Configure the things we want Spring to manage - @Configuration + context.getBean(GamingConsole.class).up(); - var context = new AnnotationConfigApplicationContext(AppConfig.class) + context.getBean(GameRunner.class).run(); + } + - // 2: Configure the things we want Spring to manage - @Configuration + System.out.println(context.getBean("name")); // Returns "Jenn" System.out.println(context.getBean("address")) // Returns error, we renamed address -> address2 @@ -404,23 +432,21 @@ record Address (String firstLine, String city) {}; public class AppConfig { @Bean - public String name() { - return "Jenn"; - } - @Bean - public int age() { - return 15; + public GamingConsole game() { + var game = new PacmanGame(); + return game; } @Bean - public Person person() { - var person = new Person("Jack", 18); - return person; - } + public GameRunner gameRunner(GamingConsole game) { + var gameRunner = new GameRunner(game); + return game; + } // Can also change new GameRunner(game) -> new GameRunner(game()) with no parameters +} - @Bean(name = "address2") - public Address address() { - return new Address("Baker Street", "London"); - } +## Tips -} \ No newline at end of file +#### List all Spring Beans +// Prints the list out to System, the :: is a method reference +// Some internal Spring Beans will be listed alongside your own defined Beans +Arrays.stream(context.getBeanDefinitionNames()).forEach(System.out::println); \ No newline at end of file From 19a33303c5763443251d3cdaab21d05afb096294 Mon Sep 17 00:00:00 2001 From: Kelsey Sterner Date: Wed, 21 Aug 2024 22:20:30 -0400 Subject: [PATCH 05/11] Update README.md --- backend/spring/README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/backend/spring/README.md b/backend/spring/README.md index bd5ce6e..9384c82 100644 --- a/backend/spring/README.md +++ b/backend/spring/README.md @@ -449,4 +449,9 @@ public class AppConfig { #### List all Spring Beans // Prints the list out to System, the :: is a method reference // Some internal Spring Beans will be listed alongside your own defined Beans -Arrays.stream(context.getBeanDefinitionNames()).forEach(System.out::println); \ No newline at end of file +Arrays.stream(context.getBeanDefinitionNames()).forEach(System.out::println); + +## More Resources +- https://www.javatpoint.com/spring-tutorial +- https://www.baeldung.com/spring-tutorial +- https://www.geeksforgeeks.org/spring/ From b899bfec930e393516f3c2c507448b5f5fc75d82 Mon Sep 17 00:00:00 2001 From: Kelsey Sterner Date: Wed, 21 Aug 2024 22:33:48 -0400 Subject: [PATCH 06/11] Update README.md --- backend/spring/README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/backend/spring/README.md b/backend/spring/README.md index 9384c82..1c5b9a8 100644 --- a/backend/spring/README.md +++ b/backend/spring/README.md @@ -7,8 +7,7 @@ This overview was created from notes following 2 youtube tutorials (links provid ## IoC Inversion of control (IoC) is a **principle** where the control of creating objects (in this case) is given to something (Ex. Spring Framework) other than the developer. In Spring this is done through a **design pattern** called dependency injection -## DI -Dependency injection in Spring +## DI - Dependency injection in Spring - Constructor injection - Setter injection - Field injection (Not recommended) @@ -18,7 +17,7 @@ Dependency injection in Spring Coupling: How much work is involved in changing something? - Tightly coupled: Engine to a car, Computer to your house (harder to move) - Loosely coupled: Tire to a car, laptop to your house (can take anywhere) -* In software, loosely coupled is often better as code is always changing and iterating to better versions +In software, loosely coupled is often better as code is always changing and iterating to better versions Tightly coupled code: SuperMario mario = new SuperMario(); @@ -70,7 +69,7 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. #### XML configuration (using Component) ex. App.java - public class App { + ```public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml") // Your own xml file and file name @@ -83,7 +82,7 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. - + ``` #### Annotation based configuration * (Components, Autowired) ex. From 609c80b4b159bc0f646614007ef11ff7fba6f14a Mon Sep 17 00:00:00 2001 From: Kelsey Sterner Date: Thu, 22 Aug 2024 00:25:42 -0400 Subject: [PATCH 07/11] Update README.md --- backend/spring/README.md | 143 +++++++++++++++++++-------------------- 1 file changed, 70 insertions(+), 73 deletions(-) diff --git a/backend/spring/README.md b/backend/spring/README.md index 1c5b9a8..ad80f22 100644 --- a/backend/spring/README.md +++ b/backend/spring/README.md @@ -67,9 +67,9 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. ### Achieving dependency injections through configuration #### XML configuration (using Component) - ex. - App.java - ```public class App { +ex. +App.java + public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml") // Your own xml file and file name @@ -77,7 +77,7 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. obj.drive(); } } - spring.xml (in src) +spring.xml (in src) @@ -85,8 +85,8 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. ``` #### Annotation based configuration * (Components, Autowired) - ex. - App.java +ex. +App.java public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml") // Your own xml file and file name @@ -95,14 +95,14 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. obj.drive(); } } - spring.xml (in src) +spring.xml (in src) - Car.java +Car.java package com.navin.Telusko; @Component // <- important public class Car implements Vehicle { @@ -112,8 +112,7 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. } #### Combo Annotation & Xml w/ Bean property tags - ex. - App.java +App.java public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml") // Your own xml file and file name @@ -122,7 +121,7 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. System.out.println(t); } } - spring.xml (in src) +spring.xml (in src) @@ -133,7 +132,7 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. - Car.java +Car.java package com.navin.Telusko; @Component // <- important @@ -143,7 +142,7 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. } } - Tire.java +Tire.java package com.navin.Telusko; public class Tire { @@ -164,8 +163,7 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. } #### Constructor Injection (Still mixed Annotation and Xml Config) & Autowired - ex. - App.java +App.java public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml") // Your own xml file and file name @@ -174,7 +172,7 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. obj.drive(); } } - spring.xml (in src) +spring.xml (in src) @@ -185,7 +183,7 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. - Car.java +Car.java package com.navin.Telusko; @Component // <- important @@ -207,7 +205,7 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. } } - Tire.java +Tire.java package com.navin.Telusko; @Component @@ -234,10 +232,10 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. } #### Annotation Confirguation using Maven (New Example) - 1. Create Maven project (Quick start maven archetype) - 2. Add dependencies to pom.xml from Maven Repository - - Spring context copy and paste - Samsung.java +1. Create Maven project (Quick start maven archetype) +2. Add dependencies to pom.xml from Maven Repository + - Spring context copy and paste +Samsung.java package com.telusko.SpringAnno; @@ -260,7 +258,7 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. } } - App.java +App.java package com.telusko.SpringAnno; public class App { @@ -272,7 +270,7 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. } } - AppConfig.java +AppConfig.java package com.telusko.SpringAnno; // import statements auto inserted here @@ -291,14 +289,14 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. } - MobileProcessor.java +MobileProcessor.java package com.telusko.SpringAnno; public interface MobileProcessor { void process(); } - Snapdragon.java +Snapdragon.java package com.telusko.SpringAnno; public class Snapdragon implements MobileProcessor { @@ -307,12 +305,11 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. } } #### Annotation Component (AutoWird Primary Qualifier) - 1. Add Component tags to Samsung and Snapdragon - 2. Add ComponentScan to AppConfig to find components (it looks by type) - - defaults to class name decapitalized (Samsung->samsung) - - With multiple components, you can define a primary (@Primary) or a qualifier (@Qualifier("id")) - - - Samsung.java +1. Add Component tags to Samsung and Snapdragon +2. Add ComponentScan to AppConfig to find components (it looks by type) + - defaults to class name decapitalized (Samsung->samsung) + - With multiple components, you can define a primary (@Primary) or a qualifier (@Qualifier("id")) +Samsung.java package com.telusko.SpringAnno; @Component @@ -336,7 +333,7 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. } } - App.java +App.java package com.telusko.SpringAnno; // Spring Core Annotations @@ -349,7 +346,7 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. } } - AppConfig.java +AppConfig.java package com.telusko.SpringAnno; // import statements auto inserted here @@ -360,14 +357,14 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. } - MobileProcessor.java +MobileProcessor.java package com.telusko.SpringAnno; public interface MobileProcessor { void process(); } - Snapdragon.java +Snapdragon.java package com.telusko.SpringAnno; // importing Component @@ -380,7 +377,7 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. } } - MediaTek.java +MediaTek.java package com.telusko.SpringAnno; // importing Component @@ -395,54 +392,54 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. ### Another Example of implementing Spring -> Hello World Application App.java -package ... - -imports + package ... -public class App { - public static void main(String[] args) { - // 1: Launch a Spring Context - try(var context = new AnnotationConfigApplicationContext(AppConfig.class)) { - // 2: Configure the things we want Spring to manage - @Configuration - context.getBean(GamingConsole.class).up(); + imports - context.getBean(GameRunner.class).run(); + public class App { + public static void main(String[] args) { + // 1: Launch a Spring Context + try(var context = new AnnotationConfigApplicationContext(AppConfig.class)) { + // 2: Configure the things we want Spring to manage - @Configuration + context.getBean(GamingConsole.class).up(); + + context.getBean(GameRunner.class).run(); + } + + + + System.out.println(context.getBean("name")); // Returns "Jenn" + System.out.println(context.getBean("address")) // Returns error, we renamed address -> address2 + + System.out.println(context.getBean(Address.class)) // Can use type of Bean + + } - - - - System.out.println(context.getBean("name")); // Returns "Jenn" - System.out.println(context.getBean("address")) // Returns error, we renamed address -> address2 - - System.out.println(context.getBean(Address.class)) // Can use type of Bean - - } -} AppConfig.java -package ... + package ... + + imports -imports + record Person (String name, int age) {}; + record Address (String firstLine, String city) {}; -record Person (String name, int age) {}; -record Address (String firstLine, String city) {}; + public class AppConfig { -public class AppConfig { + @Bean + public GamingConsole game() { + var game = new PacmanGame(); + return game; + } - @Bean - public GamingConsole game() { - var game = new PacmanGame(); - return game; + @Bean + public GameRunner gameRunner(GamingConsole game) { + var gameRunner = new GameRunner(game); + return game; + } // Can also change new GameRunner(game) -> new GameRunner(game()) with no parameters } - @Bean - public GameRunner gameRunner(GamingConsole game) { - var gameRunner = new GameRunner(game); - return game; - } // Can also change new GameRunner(game) -> new GameRunner(game()) with no parameters -} - ## Tips #### List all Spring Beans From 8c7c28779113c744c51fe9bcef066f1d5a41051d Mon Sep 17 00:00:00 2001 From: Kelsey Sterner Date: Thu, 22 Aug 2024 00:27:24 -0400 Subject: [PATCH 08/11] Update README.md --- backend/spring/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/spring/README.md b/backend/spring/README.md index ad80f22..f73316f 100644 --- a/backend/spring/README.md +++ b/backend/spring/README.md @@ -8,6 +8,7 @@ This overview was created from notes following 2 youtube tutorials (links provid Inversion of control (IoC) is a **principle** where the control of creating objects (in this case) is given to something (Ex. Spring Framework) other than the developer. In Spring this is done through a **design pattern** called dependency injection ## DI - Dependency injection in Spring +Instead of typically using ```obj = **new** Obj();``` We leave the object creation and insertion to Spring - Constructor injection - Setter injection - Field injection (Not recommended) From 1eb45bc25f9859b8421854d2d11bccebeda1d113 Mon Sep 17 00:00:00 2001 From: Kelsey Sterner Date: Thu, 22 Aug 2024 00:31:49 -0400 Subject: [PATCH 09/11] Update README.md --- backend/spring/README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/backend/spring/README.md b/backend/spring/README.md index f73316f..c9bec2d 100644 --- a/backend/spring/README.md +++ b/backend/spring/README.md @@ -3,12 +3,13 @@ This overview was created from notes following 2 youtube tutorials (links provid ## Prerequisites - Must have a solid understanding of Java and OOP (particularly interfaces) +- Must have familiarity with Maven/Gradle (2nd YouTube tutorial can provide that) ## IoC Inversion of control (IoC) is a **principle** where the control of creating objects (in this case) is given to something (Ex. Spring Framework) other than the developer. In Spring this is done through a **design pattern** called dependency injection ## DI - Dependency injection in Spring -Instead of typically using ```obj = **new** Obj();``` We leave the object creation and insertion to Spring +Instead of typically using ```Thing object = new Thing();``` We leave the object creation and insertion to Spring - Constructor injection - Setter injection - Field injection (Not recommended) @@ -34,7 +35,7 @@ GameRunner runner = new GameRunner(game2); // Because all games must implement the GameingConsole interface, GameRunner can accept any GameingConsole object in the constructor ## Spring Container/Context (IoC Container) -(is within JVM [Java Virutal Machine]) +(Spring Containers operate within the JVM [Java Virutal Machine]) - Manages Spring beans & their lifecycle - Bean Factory: Basic Spring Container (Not really used) - **Application Context**: Advanced Spring Container w/ enterprise-specific features @@ -54,9 +55,8 @@ Tutorial References (Highly recommend watching!) - https://www.youtube.com/watch?v=If1Lw4pLLEo (Fast, comprehensive, good examples) [Also has a more recentt playlist making an example project with Spring and Springboot] I watched the 2nd one first, and put the 1st on 1.5x to review. -# Gen Topics +# General Spring Topics - IoC containers (Inversion of Control) -- Data access framework - Dependency injections - Injecting object dependencies @@ -70,6 +70,7 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. #### XML configuration (using Component) ex. App.java +``` public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml") // Your own xml file and file name @@ -78,16 +79,18 @@ App.java obj.drive(); } } +``` spring.xml (in src) - ``` + #### Annotation based configuration * (Components, Autowired) ex. App.java +``` public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml") // Your own xml file and file name @@ -96,6 +99,7 @@ App.java obj.drive(); } } +``` spring.xml (in src) From 3121990e6107eeb9faae0a57d5087306d0b5fff2 Mon Sep 17 00:00:00 2001 From: Kelsey Sterner Date: Thu, 22 Aug 2024 00:36:34 -0400 Subject: [PATCH 10/11] Update README.md --- backend/spring/README.md | 55 +++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/backend/spring/README.md b/backend/spring/README.md index c9bec2d..47cad54 100644 --- a/backend/spring/README.md +++ b/backend/spring/README.md @@ -68,7 +68,7 @@ I watched the 2nd one first, and put the 1st on 1.5x to review. ### Achieving dependency injections through configuration #### XML configuration (using Component) -ex. + App.java ``` public class App { @@ -88,7 +88,7 @@ spring.xml (in src) #### Annotation based configuration * (Components, Autowired) -ex. + App.java ``` public class App { @@ -108,6 +108,7 @@ spring.xml (in src) Car.java +``` package com.navin.Telusko; @Component // <- important public class Car implements Vehicle { @@ -115,9 +116,11 @@ Car.java System.out.println("driving"); } } +``` #### Combo Annotation & Xml w/ Bean property tags App.java +``` public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml") // Your own xml file and file name @@ -126,6 +129,7 @@ App.java System.out.println(t); } } +``` spring.xml (in src) @@ -138,6 +142,7 @@ spring.xml (in src) Car.java +``` package com.navin.Telusko; @Component // <- important @@ -146,8 +151,10 @@ Car.java System.out.println("driving"); } } +``` Tire.java +``` package com.navin.Telusko; public class Tire { @@ -166,9 +173,11 @@ Tire.java return "Tire [brand=" + brand + "]"; } } +``` #### Constructor Injection (Still mixed Annotation and Xml Config) & Autowired App.java +``` public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml") // Your own xml file and file name @@ -177,6 +186,7 @@ App.java obj.drive(); } } +``` spring.xml (in src) @@ -189,6 +199,7 @@ spring.xml (in src) Car.java +``` package com.navin.Telusko; @Component // <- important @@ -209,8 +220,10 @@ Car.java System.out.println("car" + tire); } } +``` Tire.java +``` package com.navin.Telusko; @Component @@ -235,6 +248,7 @@ Tire.java return "Tire [brand=" + brand + "]"; } } +``` #### Annotation Confirguation using Maven (New Example) 1. Create Maven project (Quick start maven archetype) @@ -243,7 +257,7 @@ Tire.java Samsung.java package com.telusko.SpringAnno; - +``` public class Samsung { @Autowired // checks by type @@ -262,8 +276,10 @@ Samsung.java cpu.process(); } } +``` App.java +``` package com.telusko.SpringAnno; public class App { @@ -274,8 +290,10 @@ App.java s7.config(); } } +``` AppConfig.java +``` package com.telusko.SpringAnno; // import statements auto inserted here @@ -293,15 +311,19 @@ AppConfig.java } } +``` MobileProcessor.java +``` package com.telusko.SpringAnno; public interface MobileProcessor { void process(); } +``` Snapdragon.java +``` package com.telusko.SpringAnno; public class Snapdragon implements MobileProcessor { @@ -309,12 +331,16 @@ Snapdragon.java System.out.println("Word's best CPU"); } } +``` + #### Annotation Component (AutoWird Primary Qualifier) 1. Add Component tags to Samsung and Snapdragon 2. Add ComponentScan to AppConfig to find components (it looks by type) - defaults to class name decapitalized (Samsung->samsung) - With multiple components, you can define a primary (@Primary) or a qualifier (@Qualifier("id")) + Samsung.java +``` package com.telusko.SpringAnno; @Component @@ -337,8 +363,10 @@ Samsung.java cpu.process(); } } +``` App.java +``` package com.telusko.SpringAnno; // Spring Core Annotations @@ -350,8 +378,10 @@ App.java s7.config(); } } +``` AppConfig.java +``` package com.telusko.SpringAnno; // import statements auto inserted here @@ -361,15 +391,19 @@ AppConfig.java public class AppConfig { } +``` MobileProcessor.java +``` package com.telusko.SpringAnno; public interface MobileProcessor { void process(); } +``` Snapdragon.java +``` package com.telusko.SpringAnno; // importing Component @@ -381,8 +415,10 @@ Snapdragon.java System.out.println("Word's best CPU"); } } +``` MediaTek.java +``` package com.telusko.SpringAnno; // importing Component @@ -393,13 +429,15 @@ MediaTek.java System.out.println("2nd best CPU"); } } +``` ### Another Example of implementing Spring -> Hello World Application App.java - package ... +``` + // package ... - imports + // imports (from Spring usually) public class App { public static void main(String[] args) { @@ -421,11 +459,13 @@ App.java } } +``` AppConfig.java - package ... +``` + // package ... - imports + // imports (from Spring ususally) record Person (String name, int age) {}; record Address (String firstLine, String city) {}; @@ -444,6 +484,7 @@ AppConfig.java return game; } // Can also change new GameRunner(game) -> new GameRunner(game()) with no parameters } +``` ## Tips From 738f3ac339ddabf17e317a4ebf12cd7284a4dbfa Mon Sep 17 00:00:00 2001 From: Kelsey Sterner Date: Thu, 22 Aug 2024 00:37:57 -0400 Subject: [PATCH 11/11] Update README.md --- backend/spring/README.md | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/backend/spring/README.md b/backend/spring/README.md index 47cad54..750127e 100644 --- a/backend/spring/README.md +++ b/backend/spring/README.md @@ -448,15 +448,6 @@ App.java context.getBean(GameRunner.class).run(); } - - - - System.out.println(context.getBean("name")); // Returns "Jenn" - System.out.println(context.getBean("address")) // Returns error, we renamed address -> address2 - - System.out.println(context.getBean(Address.class)) // Can use type of Bean - - } } ``` @@ -467,9 +458,6 @@ AppConfig.java // imports (from Spring ususally) - record Person (String name, int age) {}; - record Address (String firstLine, String city) {}; - public class AppConfig { @Bean