Skip to content

5 Spring Introduction

What is the spring framework?

  • The Spring framework is the most widely used framework for the development of Java Enterprise Edition applications, specifically, web applications.

Spring框架是开发Java企业版应用程序(特别是web应用程序)使用最广泛的框架。

  • The Spring Framework is divided into modules. At the heart are the modules of the core container, including a configuration model and a dependency injection mechanism. The main usage of Spring core is to create all the objects (for example, objects that connect to database, business logic related class, etc) that your application is required for running and dependency injection to achieve the loosely decouple.

Spring框架分为多个模块。核心是核心容器的模块,包括配置模型和依赖注入机制。Spring core的主要用途是创建应用程序运行和依赖注入所需的所有对象(例如,连接到数据库的对象、与业务逻辑相关的类等),以实现松耦合

Spring Core

  • What is dependency?

The objects that the current class cooperates with.

For example:

pulic interface Connection{
  void connect();
}

public class MySqlConnection implements Connection{

}

public class PaymentAction{
  private Connection connection;

  public PaymentAction(){
    connection = new MySqlConnection(x,y,z,d);
  }

  public void makePayment(){
    connection.connect();
  }
}

These are drawbacks in this approach:

  • Massive code change if we switch to another Connection implementation later on.

    https://alanbarber.com/post/solid-principles-ocp-open-closed-principle/

    // MysqlConnection implement Connection

    // OracleConnection implement Connection

  • https://alanbarber.com/post/solid-principles-ocp-open-closed-principle/

  • Dependency Injection / Inversion of control

Instead of maintaining dependencies by the PaymentAction object, it can be injected by someone else(spring framework). This is called Dependency injection. Here are two mainstream approaches as follows:

  • Constructor injection

    @Autowired
    public PaymentAction(Connection connection){
      this.connection = connection;
    }
    
  • Field injection

    public class PaymentAction{
      @Autowired
      private Connection connection;
    }
    

    So, the example above can be converted to code below:

    @Component
    public class PaymentAction{
      private Connection connection;
    
      @Autowired
      public PaymentAction(Connection connection){
        this.connection = connection;
      }
    
      public void makePayment(){
        connection.connect();
      }
    }
    
    @Component
    public class MySqlConnection implements Connections{
    }
    
    @Component
    public class OracleConnection implements Connections{
      ...
    }
    

    从PaymentAction的角度来看, 它只是想使用connection, 不在意其是如何创建的. PaymentAction希望someone(spring)把connection实例化之后在交给PaymentAction对象, 就是用Dependency injection来实现的.

  • loC Container = ApplicationContext

  • The loC container will create the objects, wire them together, configure them, and manage their complete life cycle from creation till destruction. These objects are called Spring Beans

  • The container gets its instructions on what objects to instantiate, configure, and assemble by reading the configuration metadata provided. The configuration metadata can be represented either by XML, Java annotations, or Java code.

  • Bean = Java object

The Java object that is initialized and managed by Spring is called bean.

  • Bean scope
Scope Description
singleton (Default) A single object instance for each Spring loC container
prototype Any number of object instances

Screenshot 2023-12-09 at 16.53.51Screenshot 2023-12-09 at 16.54.13

How to configure a class as Bean in the Spring container?

  • XML based configuration https://docs.google.com/document/d/1axaMAhcAlWENBMjmcyEB7McckQwWPWJ9CgaZEh0JAqQ/edit#heading=h.f4xobmu7dnrv

  • Annotation-based configuration

Annotation-based configuration using annotations on the relevant class, method or the field so that Spring can recognize and initialize them. @Component and @Autowired

Screenshot 2023-12-09 at 16.57.19

Screenshot 2023-12-09 at 18.31.07

Right click onlineOrder package, create service package and dao package. Create CustomerDao and CustomerService class.

CustomerDao.java:

package com.example.onlineOrder.dao;

import com.example.onlineOrder.entity.Customer;
import org.springframework.stereotype.Repository;

@Repository
public class CustomerDao {
    public void signUp(Customer customer){

    }

    public Customer getCustomer(String email){
        return new Customer();
    }
}

CustomerService:

package com.example.onlineOrder.service;

import com.example.onlineOrder.dao.CustomerDao;
import com.example.onlineOrder.entity.Customer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CustomerService {
    @Autowired
    private CustomerDao customerDao;

    public void signUp(Customer customer){
        customerDao.signUp(customer);
    }

    public Customer getCustomer(String email){
        return customerDao.getCustomer(email);
    }

}

SignUpContorller:

package com.eve.onlineOrder.controller;

import com.eve.onlineOrder.entity.Customer;
import com.eve.onlineOrder.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;

@Controller
public class SignUpController {

    @Autowired
    private CustomerService customerService;

    @RequestMapping(value = "/signup", method = RequestMethod.POST)
    @ResponseStatus(value= HttpStatus.CREATED)
    public void signUp(@RequestBody Customer customer){

    }


}

onlineOrder-servlet.xml:

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

       <!-- Path: src/main/webapp/WEB-INF/onlineOrder-servlet.xml -->
       <context:component-scan base-package="com.eve.onlineOrder" />
</beans>

What does <context:component-scan base-package="..."/> mean?

  • When the spring container initializes, it searches the root and sub folders that are defined at base-package, instantiating the bean which has the @Component annotation.

How to initialize a Spring IOC container on the web app?

<!DOCTYPE web-app PUBLIC
    "-//Sun Microsystems,Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>

    <display-name>OnlineOrder Website</display-name>

    <servlet>
        <servlet-name>onlineOrder</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>onlineOrder</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
  • Java-based configuration
  • Using Java based configuration allows you to write your Spring configuration without using XML. Java based configuration uses the @Configuration-annotated classes and @Bean-annotated methods.
  • Using @Configuration annotation indicates that Spring loC container can use it as a source of Bean definitions. Using the @Bean tells Spring that the method will return an object which should be registered as a bean in the Spring container.
  • https://www.baeldung.com/spring-xml-vs-java-config

For example, our ApplicationConfig.java

@Configuration
public class ApplicationConfig{
  @Bean(name="sessionFactory")
  public LocalSessionFactoryBean sessionFactory(){
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(dataSource());
    sessionFactory.setPackagesToScan("com.laioffer.onlineOrder.entity");
    sessionFactory.setHibernateProperties(hibernateProperties());
    return sessionFactory;
  } 

  @Bean(name="dataSource")
  public DataSource dataSource(){
    String RDS_INSTANCE="";
    String USERNAME="";
    String PASSWORD="";
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql://" + RDS_INSTANCE + ":3306/onlineOrder?createDatabaseIfNotExist=true&&serverTimezone=UTC");
    dataSource.setUsername(USERNAME);
    dataSource.setPassword(PASSWORD);

    return dataSource;
  }
}

Why do we choose Spring?

  • Versatile: We can integrate any technologies with spring, such as hibernate, structs, etc.
  • Modularity: We've options to use the entire Spring framework or just the modules necessary. Morever, we can optionally include one or more Spring projects depending upon the need.
  • End-to-End Development: Spring supports all aspects of application development, Web aspects, Business aspects, Persistence aspects, etc, so we can develop a complete application using spring.

Summary:

  1. 什么是dependency?类的成员变量
  2. 什么是loC container? 生成Bean实例的工厂, 并且管理容器中的Bean
  3. 什么是dependency injection? 容器将所需要的依赖注入到类中的过程
  4. 什么是inversion of control? 不在主动创建依赖, 而是通过上游(Spring framework)来提供