Spring5学习笔记

Posted dingwen_blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring5学习笔记相关的知识,希望对你有一定的参考价值。

文章目录

Spring5学习笔记

[!TIP]

笔记总结自哔哩哔哩狂神说Spring5

1. 简介

1.1 介绍

[!NOTE]

Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。

Spring是分层的java SE/EE应用的full-stack的轻量级开源框架,以IOC(Inverse of control:控制反转) 和 AOP(Aspect Oriented Programming: 面向切面编程)为内核,提供了展现层spring MVC和持久层 Spring JDBCTemplate以及业务层事务管理等企业级应用技术,能整合各类第三方框架和类库,是一个技术大杂烩。

1.2 发展历程

[!NOTE]

  • 2002年,Rod Jahnson首次推出了Spring框架雏形interface21框架
  • 2004年3月24日,Spring框架以interface21框架为基础,经过重新设计,发布了1.0正式版

1.3 理念

[!NOTE]

使现有技术更加实用,更加简单。

1.4 优点

  • 开源免费的容器框架
  • 轻量级的非入侵式框架
  • 优秀的事务支持

[!NOTE]

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架)。

1.4 组成

1.4.1 Spring Core

[!NOTE]

核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转(IOC)将应用程序的配置和依赖性规范与实际的应用程序代码分开。

1.4.2 Spring Context

[!NOTE]

Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。

1.4.3 Spring AOP

[!NOTE]

通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能 , 集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理任何支持 AOP的对象。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖组件,就可以将声明性事务管理集成到应用程序中。

1.4.4 Spring DAO

[!NOTE]

JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。

1.4.5 Spring ORM

[!NOTE]

Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。

1.4.6 Spring Web

[!NOTE]

Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。

1.4.7 Spring Web MVC

[!NOTE]

MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

1.5 扩展

  • 现代化的java开发,就是基于Spring的开发
  • Spring Boot
    • 快速开发脚手架
  • Spring Cloud
    • 多个Spring Boot

2. 控制反转

2.1 原型

2.1.1 UserDao

package com.dingwen.stu.spr.dao;

/**
 * 用户 dao
 *
 * @author dingwen
 * @date 2021/10/05
 */
public interface UserDao 
    /**
     * 通过ID查询用户信息
     *
     * @param id id
     */
    void selectById(String id);

2.1.2 UserDaomysqlImpl

package com.dingwen.stu.spr.dao.impl;

import com.dingwen.stu.spr.dao.UserDao;

/**
 * 用户 dao impl
 * mysql 实现
 *
 * @author dingwen
 * @date 2021/10/05
 */
public class UserDaoMysqlImpl implements UserDao 
    @Override
    public void selectById(String id) 
        System.out.println("dao 通过用户ID查询用户信息,mysql实现");
    

2.1.3 UserDaoOracleImpl

package com.dingwen.stu.spr.dao.impl;

import com.dingwen.stu.spr.dao.UserDao;

/**
 * 用户 dao impl
 * mysql 实现
 *
 * @author dingwen
 * @date 2021/10/05
 */
public class UserDaoOracleImpl implements UserDao 
    @Override
    public void selectById(String id) 
        System.out.println("dao 通过用户ID查询用户信息,Oracle实现");
    

2.1.4 UserService

package com.dingwen.stu.spr.service;

/**
 * 用户服务
 *
 * @author dingwen
 * @date 2021/10/05
 */
public interface UserService 
    /**
     * 通过ID查询用户信息
     *
     * @param id id
     */
    void selectById(String id);


2.1.5 UserServiceImpl

2.1.5.1 实现方式一
package com.dingwen.stu.spr.service.impl;

import com.dingwen.stu.spr.dao.UserDao;
import com.dingwen.stu.spr.service.UserService;

/**
 * 用户服务impl
 *
 * @author dingwen
 * @date 2021/10/05
 */
public class UserServiceImpl implements UserService 
    /**
     * 用户 dao
     */
    private UserDao userDao = new UserDaoMysqlImpl();
 	  private UserDao userDao = new UserDaoOracleImpl();

    @Override
    public void selectById(String id) 
        userDao.selectById(id);
    


[!NOTE]

用户的需求会影响我们原来的代码,我们需要根据用户的需求去修改源代码,如果程序代码量十分大,修改一次的成本代价十分昂贵。

2.1.5.2 实现方式二
package com.dingwen.stu.spr.service.impl;

import com.dingwen.stu.spr.dao.UserDao;
import com.dingwen.stu.spr.service.UserService;

/**
 * 用户服务impl
 *
 * @author dingwen
 * @date 2021/10/05
 */
public class UserServiceImpl implements UserService 
    /**
     * 用户 dao
     */
    private UserDao userDao;


    public void setUserDao(UserDao userDao) 
        this.userDao = userDao;
    

    @Override
    public void selectById(String id) 
        userDao.selectById(id);
    

[!NOTE]

之前,程序是主动创建对象,控制权在程序员手上,使用了set注入之后,程序不再有主动性,而是变成了被动的接受对象。这种思想从本质上实现了问题,程序员不用再去管理对象的创建了。系统的耦合性大大降低,可以更加专注的在业务的实现上,这是IOC的原型。

2.2 本质

[!NOTE]

控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法。没有IoC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。

采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。

3. Hello Spring

3.1 依赖

  			<!--spring-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.17.RELEASE</version>
        </dependency>

3.2 Hello实体

public class Hello 
    private String str;

    public String getStr() 
        return str;
    

    public void setStr(String str) 
        this.str = str;
    

    @Override
    public String toString() 
        return "Hello" +
                "str='" + str + '\\'' +
                '';
    

3.3 Spring配置文件

[!TIP]

文件名称随意。

<?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.xsd">

    <!--bean就是java对象 , 由Spring创建和管理

    类型 变量名 = new 类型();
    Hello hello = new Hello();
    bean = 对象   new Hello();
    id = 变量名
    class = new的对象
    property 相当于给对象中的属性设置一个变量
    -->
    <bean id="hello" class="nuc.ss.pojo.Hello">
        <property name="str" value="Spring"/>
    </bean>

</beans>

3.4 测试

public class MyTest 
    public static void main(String[] args) 
        // 获取Spring的上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //我们的对象现在都在Spring中管理了,我们要使用,直接去里面取出来就可以
        Hello hello = (Hello)context.getBean("hello");
        System.out.println(hello);
    

3.5 总结

[!NOTE]

  • 程序创建对象改为由Spring来创建对象
  • 反转:程序本身不创建对象 , 而变成被动的接收对象
  • 依赖注入

4. 配置

4.1 别名配置

[!NOTE]

可以添加多个别名,通过别名也能获取到该对象。

 <alias name="userServiceImpl" alias="userService"></alias>
 <alias name="userServiceImpl" alias="test"></alias>

4.2 Bean配置

[!NOTE]

  • id:bean的唯一标识符,也就是相当于我们学的对象名
  • class:bean 对象所对应的权限定名:包名 + 类型
  • name: 也是别名,而且name更高级,可以起多个别名,通过逗号空格分号等分割
<bean id="userDaoOracleImpl" class="com.dingwen.stu.spr.dao.impl.UserDaoOracleImpl" name="userDaoOracleImpl,t2 t3">
    <property name="userDao" ref="userDaoOracleImpl"></property>
</bean>

4.3 import

[!NOTE]

团队的合作通过import来实现 ,可以将多个配置文件,导入合并为一个。

 <import resource="beans2.xml"></import>

5. 依赖注入

[!NOTE]

  • 依赖:指Bean对象的创建依赖于容器
  • 注入: 指Bean对象所依赖的资源 , 由容器来设置和装配

5.1 构造器注入

[!NOTE]

默认使用无参构造。

5.1.1 使用无参构造创建对象

<!--无参构造器-->
<bean id="user" class="nuc.ss.pojo.User">
    <!--set 方法必须-->
    <property name="name" value="dingwen"/>
</bean>

5.1.2 使用有参构造创建对象

   private String name;
    private int age;
    public UserDaoOracleImpl(String name, int age) 
        System.out.println("name = " + name);
        System.out.println("age = " + age);
        System.out.println("UserDaoOracleImpl constructor");
    
5.1.2.1 下标赋值
<bean id="userDaoOracleImpl" class="com.dingwen.stu.spr.dao.impl.UserDaoOracleImpl">
        <constructor-arg index="0" value="dingwen"></constructor-arg>
        <constructor-arg index="1" value="23"></constructor-arg>
</bean>
5.1.2.2 参数类型赋值
  <bean id="userDaoOracleImpl" class="com.dingwen.stu.spr.dao.impl.UserDaoOracleImpl">
        <constructor-arg type="java.lang.String" value="dingwen"></constructor-arg>
        <constructor-arg type="int" value="23"></constructor-arg>
 </bean>

[!NOTE]

只适用于同一类型参数只有一个多情况下使用。

5.1.2.3 参数名称赋值
     <bean id="userDaoOracleImpl" class="com.dingwen.stu.spr.dao.impl.UserDaoOracleImpl">
       <constructor-arg name="name" value="dingwen"></constructor-arg>
       <constructor-arg name="age" value="23"></constructor-arg>
    </bean>

5.2 set()方式注入

5.2.1 实体准备

5.2.1.1 Address
package com.dingwen.stu.spr.di.entity;

/**
 * 地址
 *
 * @author dingwen
 * @date 2021/10/05
 */
public class Address 
    /**
     * 地址
     */
    private String address;

    public String getAddress() 
        return address;
    

    public void setAddress(String address) 
        this.address = address;
    

    @Override
    public String toString() 
        return "Address" +
                "address='" + address + '\\'' +
                '';
    

5.2.1.2 Student
package com.dingwen.stu.spr.di.entity;

import java.util.*;

/**
 * 学生
 *
 * @author dingwen
 * @date 2021/10/05
 */
public class Student 
    /**
     * 名字
     */
    private String name;

    /**
     * 家庭地址
     */
    private Address address;

    /**
     * 书
     */
    private String[] books;

    /**
     * 爱好
     */
    private List<String> hobbies;

    /**
     * 银行卡
     */
    private Map<String,String> cards;

    /**
     * 游戏
     */
    private Set<String> games;

    /**
     * 是否结婚
     */
    private boolean isWife;

    /**
     * 信息
     */
    private Properties info;

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

    public Address getAddressSpring5学习笔记

Spring5学习笔记

Spring5学习笔记(14) — “Spring5 声明式事务管理”

Spring5学习笔记(14) — “Spring5 声明式事务管理”

Spring | Spring5学习笔记 #yyds干货盘点#

尚硅谷Spring学习笔记-- Spring5新功能