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
-
Field injection
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 |
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
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:
- 什么是dependency?类的成员变量
- 什么是loC container? 生成Bean实例的工厂, 并且管理容器中的Bean
- 什么是dependency injection? 容器将所需要的依赖注入到类中的过程
- 什么是inversion of control? 不在主动创建依赖, 而是通过上游(Spring framework)来提供