🖍️
Developer Note
  • Welcome
  • Git
    • Eslint & Prettier & Stylelint & Husky
  • Programming Language
    • JavaScript
      • Script Async vs Defer
      • Module
      • Const VS Let VS Var
      • Promise
      • Event Loop
      • Execution Context
      • Hoisting
      • Closure
      • Event Buddling and Capturing
      • Garbage Collection
      • This
      • Routing
      • Debounce and Throttle
      • Web Component
      • Iterator
      • Syntax
      • String
      • Array
      • Object
      • Proxy & Reflect
      • ProtoType
      • Class
      • Immutability
      • Typeof & Instanceof
      • Npm (Node package manager)
    • TypeScript
      • Utility Type
      • Type vs Interface
      • Any vs Unknown vs Never
      • Void and undefined
      • Strict Mode
      • Namespace
      • Enum
      • Module
      • Generic
    • Python
      • Local Development
      • Uv
      • Asyncio & Event loop
      • Context Manager
      • Iterator & Generator
      • Fast API
      • Pydantic & Data Class
    • Java
      • Compilation and Execution
      • Data Type
      • Enumeration
      • Data Structure
      • Try Catch
      • InputStream and OutputStream
      • Concurrent
      • Unicode Block
      • Build Tools
      • Servlet
      • Java 8
  • Coding Pattern
    • MVC vs MVVM
    • OOP vs Functional
    • Error Handling
    • MVC vs Flux
    • Imperative vs Declarative
    • Design Pattern
  • Web Communication
    • REST API
      • Web Hook
      • CORS issue
    • HTTPS
    • GraphQL
      • REST API vs GraphQL
      • Implementation (NodeJS + React)
    • Server-Sent Event
    • Web Socket
    • IP
    • Domain Name System (DNS)
  • Frontend
    • Progressive Web App (PWA)
    • Single Page & Multiple Page Application
    • Search Engine Optimiaztion (SEO)
    • Web bundling & Micro-frontend
      • Webpack
        • Using Webpack to build React Application
        • Using Webpack to build react library
      • Vite
      • Using rollup to build react library
      • Implementing micro frontend
    • Web Security
      • CSRF & Nonce
      • XSS
      • Click hijacking
    • Cypress
    • CSS
      • Core
        • Box Model
        • Inline vs Block
        • Flexbox & Grid
        • Pseudo Class
        • Position
      • Tailwind CSS
        • Shadcn
      • CSS In JS
        • Material UI
    • React
      • Core
        • Component Pattern
        • React Lazy & Suspense
        • React Portal
        • Error Boundary
        • Rendering Methods
        • Environment Variable
        • Conditional CSS
        • Memo
        • Forward Reference
        • High Order Component (HOC) & Custom Hook
        • TypeScript
      • State Management
        • Redux
        • Recoil
        • Zustand
      • Routing
        • React Router Dom
      • Data Fetching
        • Axios & Hook
        • React Query
        • Orval
      • Table
        • React Table
      • Form & Validation
        • React Hook Form
        • Zod
      • NextJS
        • Page Router
        • App Router
      • React Native
    • Angular
    • Svelte
      • Svelte Kit
  • Backend
    • Cache
      • Browser Cache
      • Web Browser Storage
      • Proxy
      • Redis
    • Rate limit
    • Monitoring
      • Logging
      • Distributed Tracing
    • Load Test
    • Encryption
    • Authentication
      • Password Protection
      • Cookie & Session
      • JSON Web Token
      • SSO
        • OAuth 2.0
        • OpenID Connect (OIDC)
        • SAML
    • Payment
      • Pre-built
      • Custom
    • File Handling
      • Upload & Download (Front-end)
      • Stream & Buffer
    • Microservice
      • API Gateway
      • Service Discovery
      • Load Balancer
      • Circuit Breaker
      • Message Broker
      • BulkHead & Zipkin
    • Elastic Search
    • Database
      • SQL
        • Group By vs Distinct
        • Index
        • N + 1 problem
        • Normalization
        • Foreign Key
        • Relationship
        • Union & Join
        • User Defined Type
      • NOSQL (MongoDB)
      • Transaction
      • Sharding
      • Lock (Concurrency Control)
    • NodeJS
      • NodeJS vs Java Spring
      • ExpressJS
      • NestJS
        • Swagger
        • Class Validator & Validation Pipe
        • Passport (Authentication)
      • Path Module
      • Database Connection
        • Integrating with MYSQL
        • Sequalize
        • Integrating with MongoDB
        • Prisma
        • MikroORM
        • Mongoose
      • Streaming
      • Worker Thread
      • Passport JS
      • JSON Web Token
      • Socket IO
      • Bull MQ
      • Pino (Logging)
      • Yeoman
    • Spring
      • Spring MVC
      • Spring REST
      • Spring Actuator
      • Aspect Oriented Programming (AOP)
      • Controller Advice
      • Filter
      • Interceptor
      • Concurrent
      • Spring Security
      • Spring Boot
      • Spring Cloud
        • Resilience 4j
      • Quartz vs Spring Batch
      • JPA and Hibernate
      • HATEOS
      • Swagger
      • Unit Test (Java Spring)
      • Unit Test (Spring boot)
  • DevOp
    • Docker
    • Kubernetes
      • Helm
    • Nginx
    • File System
    • Cloud
      • AWS
        • EC2 (Virtual Machine)
        • Network
        • IAM
          • Role-Service Binding
        • Database
        • Route 53
        • S3
        • Message Queue
        • Application Service
        • Serverless Framework
        • Data Analysis
        • Machine Learning
        • Monitoring
        • Security
      • Azure
        • Identity
        • Compute Resource
        • Networking
        • Storage
        • Monitoring
      • Google Cloud
        • IAM
          • Workload Identity Federation
        • Compute Engine
        • VPC Network
        • Storage
        • Kubernetes Engine
        • App Engine
        • Cloud function
        • Cloud Run
        • Infra as Code
        • Pub/Sub
    • Deployment Strategy
    • Jenkins
    • Examples
      • Deploy NextJS on GCP
      • Deploy Spring on Azure
      • Deploy React on Azure
  • Domain Knowledge
    • Web 3
      • Blockchain
      • Cryptocurrency
    • AI
      • Prompt
      • Chain & Agent
      • LangChain
      • Chunking
      • Search
      • Side Products
Powered by GitBook
On this page
  • Inversion Of Control (IOC)
  • Dependency Injection
  • Initial
  • Dependency Injection (by constructor)
  • Dependency Injection (by setter)
  • Why Spring?
  • Structure of Java Spring
  • Data Access Integration
  • Web
  • Core
  • Bean
  • Introduction
  • Scope
  • Life Cycle
  • Dependency Injection
  • Auto Wire
  • Configuration
  • Component Scanning
  • Introduction
  • Component
  • Service
  • Repository
  • Controller
  • RestController

Was this helpful?

  1. Backend

Spring

Inversion Of Control (IOC)

  • If class A depend on class B , pass the declaration of class B to third party to declare

  • Example: If a graduate want to find a suitable job , he should find the agent to help him to look for his suitable job according to his abilities, instead of every student find for the same job.

  • Dependency injection is a one of the example of inversion of control

  • Without IOC

public class Graduate {
    private Programmer programmer;
}
// That assume all the graduate must find a programmer job, which is strongly coupled
  • With IOC

public class Graduate{
    private Job job;
    public void setJob(Job job){
        this.job = job;
    }
}

// The job class is an interface;
// The job of the graduate will handled by another class(e.g Main class)
// which make the graduate loosely coupled with Job class

Dependency Injection

Initial

public class Lesson{
    private Student student;
    public Lesson(){
        this.student = new Student();
    }
}

Dependency Injection (by constructor)

public class Lesson{
    private Student student;
    public Lesson(Student exampleStudent){
        this.student = exampleStudent;
    }
}

Dependency Injection (by setter)

public class Lesson{
    private Student student;
    public void setStudent(student exampleStudent){
        this.student = new Student();
    }
}
  • Initially, lesson class is fixed with a specific student class. If we declare new Lesson class, the student must be the same as every lesson class, which will cause out coupling.

  • By using dependency injection, lesson class and student will be independent to each other.

Why Spring?

  • It has strong IOC container (Application Context) which manage and create the beans

  • Developer can do dependency injection easily by using the bean of container

Structure of Java Spring

Data Access Integration

  • Provide several popular API , such as hibernate, JPA

  • Make the syntax of connecting database simpler

Web

  • Provide several web function, such as file reader

  • Define Controller, Model and View

Core

  • Application Context Container or Bean Factory Container is a container to contain the bean factory which is a xml file traditionally

  • Application Context Container

package com.yiibai;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class MainApp {
   public static void main(String[] args) {
      XmlBeanFactory factory = new XmlBeanFactory
                             (new ClassPathResource("Beans.xml"));

      HelloWorld obj = (HelloWorld) factory.getBean("helloWorld");
      obj.getMessage();
   }
}
  • Bean Factory Container

package com.yiibai;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class MainApp {
   public static void main(String[] args) {
      XmlBeanFactory factory = new XmlBeanFactory
                             (new ClassPathResource("Beans.xml"));

      HelloWorld obj = (HelloWorld) factory.getBean("helloWorld");
      obj.getMessage();
   }
}

Bean

Introduction

  • Bean can be instantiated as a instance of the class, which is similar with the below syntax to declare the new instance - sample Student

Student sampleStudent = new Student("Chan Tai Man", 12);
  • Bean can rely on another beans by using auto wire

  • Example of creating bean by using traditional xml

// HelloWorld.java
package com.yiibai;

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }

   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
}

// MainApp.java
package com.yiibai;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = 
             new ClassPathXmlApplicationContext("Beans.xml");

      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");

      obj.getMessage();
   }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id="helloWorld" class="com.yiibai.HelloWorld">
       <property name="message" value="Hello World!"/>
   </bean>

</beans>

// Your Message : Hello World!

Scope

Type

  • There are 5 types of scope - singleton, prototype, request, session and global session

  • Singleton: This scopes the bean definition to a single instance per Spring IoC container (default)

  • Prototype: This scopes a single bean definition to have any number of object instances.

  • Request: This scopes a bean definition to an HTTP request. Only valid in the context of a web-aware Spring Application Context.

  • Session: This scopes a bean definition to an HTTP session. Only valid in the context of a web-aware Spring Application Context.

  • Global-session: This scopes a bean definition to a global HTTP session. Only valid in the context of a web-aware Spring Application Context.

Singleton vs Prototype

// Main.java
package com.yiibai;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = 
             new ClassPathXmlApplicationContext("Beans.xml");

      HelloWorld objA = (HelloWorld) context.getBean("helloWorld");

      objA.setMessage("I'm object A");
      objA.getMessage();

      HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
      objB.getMessage();
   }
}
  • Singleton

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id="helloWorld" class="com.yiibai.HelloWorld" 
      scope="singleton">
   </bean>

</beans>

Output

Your Message : I'm object A
Your Message : I'm object A
  • Prototype

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id="helloWorld" class="com.yiibai.HelloWorld" 
      scope="prototype">
   </bean>

</beans>

Output

Your Message : I'm object A
Your Message : null

Life Cycle

  • Initialize and Destroy

  • we can add custom event for each as a listener

// HelloWorld.java
package com.yiibai;

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }
   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
   public void init(){
      System.out.println("Bean is going through init.");
   }
   public void destroy(){
      System.out.println("Bean will destroy now.");
   }
}
// Main.java
package com.yiibai;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {

      AbstractApplicationContext context = 
                          new ClassPathXmlApplicationContext("Beans.xml");

      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      obj.getMessage();
      context.registerShutdownHook();
   }
}
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id="helloWorld" 
       class="com.yiibai.HelloWorld"
       init-method="init" destroy-method="destroy">
       <property name="message" value="Hello World!"/>
   </bean>

</beans>

Output:

Bean is going through init.
Your Message : Hello World!
Bean will destroy now.

Dependency Injection

  • By constructor

package x.y;

public class Foo {
   public Foo(Bar bar, Baz baz) {
      // ...
   }
}
<beans>
   <bean id="foo" class="x.y.Foo">
      <constructor-arg ref="bar"/>
      <constructor-arg ref="baz"/>
   </bean>

   <bean id="bar" class="x.y.Bar"/>
   <bean id="baz" class="x.y.Baz"/>
</beans>
  • By setter

package com.yiibai;

public class TextEditor {
   private SpellChecker spellChecker;

   // a setter method to inject the dependency.
   public void setSpellChecker(SpellChecker spellChecker) {
      System.out.println("Inside setSpellChecker." );
      this.spellChecker = spellChecker;
   }
   // a getter method to return spellChecker
   public SpellChecker getSpellChecker() {
      return spellChecker;
   }

   public void spellCheck() {
      spellChecker.checkSpelling();
   }
}
<?xml version="1.0" encoding="UTF-8"?>
<? Method 1 ?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <!-- Definition for textEditor bean -->
   <bean id="textEditor" class="com.yiibai.TextEditor">
      <property name="spellChecker" ref="spellChecker"/>
   </bean>

   <!-- Definition for spellChecker bean -->
   <bean id="spellChecker" class="com.yiibai.SpellChecker">
   </bean>

</beans>
<?xml version="1.0" encoding="UTF-8"?>
<? Method 2 ?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <!-- Definition for textEditor bean using inner bean -->
   <bean id="textEditor" class="com.yiibai.TextEditor">
      <property name="spellChecker">
         <bean id="spellChecker" class="com.yiibai.SpellChecker"/>
       </property>
   </bean>

</beans>

Auto Wire

By Type / By Name (XML)

package com.yiibai;

public class TextEditor {
   private SpellChecker spellChecker;
   private String name;

   public void setSpellChecker( SpellChecker spellChecker ){
      this.spellChecker = spellChecker;
   }
   public SpellChecker getSpellChecker() {
      return spellChecker;
   }

   public void setName(String name) {
      this.name = name;
   }
   public String getName() {
      return name;
   }

   public void spellCheck() {
      spellChecker.checkSpelling();
   }
}
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <!-- Definition for textEditor bean -->
   <bean id="textEditor" class="com.yiibai.TextEditor" 
      autowire="byType">
      <property name="name" value="Generic Text Editor" />
   </bean>

   <!-- Definition for spellChecker bean -->
   <bean id="spellChecker" class="com.yiibai.SpellChecker">
   </bean>

</beans>
  • In text editor, it will look for the bean containing spell checker type or the same name automatically and inject into text editor

By Type (Annotation)

package com.yiibai;

import org.springframework.beans.factory.annotation.Autowired;

public class TextEditor {
   private SpellChecker spellChecker;

   @Autowired
   public void setSpellChecker( SpellChecker spellChecker ){
      this.spellChecker = spellChecker;
   }
   
   public SpellChecker getSpellChecker( ) {
      return spellChecker;
   }
   
   public void spellCheck() {
      spellChecker.checkSpelling();
   }
}
  • In text editor, it will look for the bean containing spell checker type automatically and inject into text editor

  • If spellchecker is a interface , make sure that it should be implemented by one class only

By Name (Annotation)

  • If a spell checker may be a interface and implement by several class, so we should look for the bean according to the name of the bean

package com.yiibai;

import org.springframework.beans.factory.annotation.Autowired;

public class TextEditor {
   private SpellChecker spellChecker;

   @Resource(name = "sampleSpellerChecker")
   public void setSpellChecker( SpellChecker spellChecker ){
      this.spellChecker = spellChecker;
   }
   
   public SpellChecker getSpellChecker( ) {
      return spellChecker;
   }
   
   public void spellCheck() {
      spellChecker.checkSpelling();
   }
}

Configuration

In spring, we can make good use of annotation instead of configure xml file

Annotation

package com.yiibai;

import org.springframework.context.annotation.*;

@Configuration
public class HelloWorldConfig {

   @Bean 
   public HelloWorld helloWorld(){
      return new HelloWorld();
   }
}

XML

<beans>
   <bean id="helloWorld" class="com.yiibai.HelloWorld" />
</beans>

Component Scanning

Introduction

  • Initially, we need to declare each bean one by one. Now, we can make good use of annotation to mark the class as a component, and perform scanning on spring container which can be in xml or java code , that will register the bean automatically for class who is marked as a component

@Configuration
@ComponentScan("com.luv2code")
@PropertySource("classpath:sport.properties")
public class SportConfig {
    @Bean
    public FortuneService normalFortuneService(){
        return new NormalFortuneService();
    }

    @Bean
    public Coach swimCoach(){
        return new SwimCoach(normalFortuneService());
    }
}
  • There are common 5 annotations to create beans

Component

  • It can be used in different layers

  • Not recommended to use

@Component
public class UserComponentImpl implements IUser {
    private String name = "UserComponentImpl";

    public String get() {
        return name;
    }
}

@Component(value="componentBeanId")
public class UserComponentImplWithParam implements IUser {
    private String name = "UserComponentImplWithParam";

    public String get() {
        return name;
    }
}
@SpringBootApplication
public class ComponentApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(ComponentApplication.class, args);
    
        IUser userComponentImpl1 = (UserComponentImpl)context.getBean("userComponentImpl");
        System.out.println(userComponentImpl1.get());
    
        IUser userComponentImpl2 = (UserComponentImplWithParam)context.getBean("componentBeanId");
        System.out.println(userComponentImpl2.get());
    }
}

// Output:
// UserComponentImpl
// UserComponentImplWithParam

Service

  • It is one part of the component

  • Mainly responsible for the business logic

  • In the most situation, it should be a interface and implemented by different class

public interface TestService {
    public void test();
}
@Service
@Scope("singleton")
public class TestServiceImpl implements TestService {
    @Override
    public void test(){
        ...
    }
}

Repository

  • It is one part of the component

  • Mainly responsible for visiting database and locate in the dao folder

@Repository
public interface LocationRepository extends JpaRepository<Location,Integer> {
    List<Location> findByName(String name);
}

Controller

  • It is one part of the component

  • used to handle URL and can used to return jsp file

  • Example 1 (Return jsp File)

@Controller
@RequestMapping("/test/{id}")
public class PathVariableTest {

    @RequestMapping("/{name}/get.do")
    public String get (@PathVariable("id") Integer index, Model model) {
        model.addAttribute("id", index);
        return "/index";
    }
}
  • Example 2 (return string or other type)

@Controller
@GetMapping("/bi")
public class ResponseBodyTest {

    @RequestMapping("/login")
    @ResponseBody
    public String get () {
        return "Hello Spring Boot!";
    }
}

RestController

  • It is one part of the controller

  • act as a api end point and must be return in string or other type

  • RestController = Controller + ResponseBody

@RestController
@RequestMapping("/bi")
public class ResponseBodyTest {
    @GetMapping("/login") 
    public String get () {
        return "Hello Spring Boot!";
    }
}
PreviousYeomanNextSpring MVC

Last updated 1 year ago

Was this helpful?