Spring5学习记录(待完成)


Spring5学习记录

2022.01.09 杭州滨江

1,Spring

1.1,简介

? Spring起源与interface21

? Spring是一个开源框架,它由[Rod Johnson](https://baike.baidu.com/item/Rod Johnson)创建。它是为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。

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

? spring的理念:使现有技术更加容易使用,本身是一个大杂烩

官网:https://spring.io/projects/spring-framework

源码地址:https://repo.spring.io/ui/native/release/org/springframework/spring

Github地址:https://github.com/spring-projects/spring-boot

maven核心依赖


    org.springframework
    spring-web
    5.3.14


  
    org.springframework
    spring-jdbc
    5.3.14

1.2,spring优点

  • 开源免费的框架(容器)
  • 轻量级(依赖包很小)的、非入侵式(对以前的框架影响不大)的框架
  • 控制反转(IOC)、面向切面(AOP)
  • 支持对事务的处理,对框架整合的支持

Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架

1.3,组成

image-20220109154212847

1.4,扩展

现代化的java开发——基于spring开发

image-20220109154639496

  • SpringBoot
    • 一个快速开发的脚手架
    • 基于SpringBoot可以快速开发单个微服务
    • 约定大于配置
  • SpringCloud
    • SpringCloud是基于SpringBoot开发

? 大多数的公司都是使用SpringBoot进行快速开发,规模更大的公司使用SpringCloud进行集群开发。学习springBoot的前提是学习Spring和spingMvc!

弊端:发展太久后,违背了原来的初衷(使开发更加容易),杂糅的东西太多,配置十分繁琐(人称“配置地狱”)。

2,IOC理论推导

原有的代码编程流程:daoImpl→dao→serviceImpl→service

缺点:每次修改需求都会涉及到底层的引用修改,如果修改代码的量比较大(代价昂贵)就得不偿失!

public class UserServiceImpl implements UserService {

//    private UserDao userDao = new UserDaoImpl();
//    private UserDao userDao = new UserDaoPgImpl();
    private UserDao userDao;

    // 利用set方法实现动态注入
    @Override
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void getUser() {
        userDao.getUser();
    }
}
  • 之前,程序是主动创建对象!控制权在程序员手中
  • 使用set注入后,程序不再具有主动性,而是变成了被动的接收对象

? 这种思想,从本质上解决了问题:程序员不用再去管理对象的创建,系统的耦合性大大降低,可以更加专注于业务的实现上!(IOC的原型

image-20220109165618006

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

解耦过程

Spring依赖注入流程

3,HelloSpring

使用beans.xml注入实体类

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


    
    
        
    


最基础的容器获取

public class XmlIocTest {
    public static void main(String  [] args) {
        // 获取spring的上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        // 我们的对象现在都在Spring中管理了,使用的时候直接取出即可
        Hello hello = (Hello) context.getBean("hello");
        System.out.println(hello);
    }
}

? 当然还有其他的注入方式,例如现在主要使用的注解注入以及其他的文件注入。

IOC一句话概括就是:由spring创建、管理、装配对象!

? 由容器创建的对象是单例

public class XmlIocTest {
    public static void main(String  [] args) {
        // 获取spring的上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-properties/beans.xml");
        // 我们的对象现在都在Spring中管理了,使用的时候直接取出即可
        Hello hello = (Hello) context.getBean("hello");
        Hello hello2 = (Hello) context.getBean("hello");
        System.out.println(hello == hello2);
    }
}
/*
true
*/

直接使用SpringXml装配

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

    
    
    

    
        
        
    


public class IocTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-properties/user.xml");
        UserService userService = (UserService) context.getBean("userService");
        userService.getUser();
    }
}

4,IOC创建对象方式

1,无参构造创建对象(默认)

    
        
    
public class XmlIocTest {
    public static void main(String  [] args) {
        // 获取spring的上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-properties/beans.xml");
        // 我们的对象现在都在Spring中管理了,使用的时候直接取出即可
        Hello hello = (Hello) context.getBean("hello");
        hello.show();
    }
}

2,使用有参构造创建对象

public class Hello {
    private String str;

    public Hello(String str) {
        this.str = str;
        System.out.println("有参构造初始化hello对象! ");
    }

    public String getStr() {
        return str;
    }

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

    public void show(){
        System.out.println("数据=>"+str);
    }
}

①下标幅值

    
        
    

②类型幅值

    
        
    

③入参名幅值

    
        
    

? 在配置文件加载的时候,容器中管理的对象就已经初始化了

5,Spring配置

5.1,别名

    
        
    
    
        // 获取spring的上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-properties/beans.xml");
        // 我们的对象现在都在Spring中管理了,使用的时候直接取出即可
        Hello hello = (Hello) context.getBean("helloRandom");
        hello.show();

5.2,Bean的配置

name本质也是一个别名,可以一次设置多个(空格和逗号分割)

    
        
    
        // 获取spring的上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-properties/beans.xml");
        // 我们的对象现在都在Spring中管理了,使用的时候直接取出即可
        Hello hello = (Hello) context.getBean("h2");
        hello.show();

5.3,import

一般用于团队开发,可以将多个配置文件(例如:beans.xml和user.xml)导入合并为1个

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


    
    
    

6,DI(依赖注入)

Dependency Injection

6.1,构造器注入

? 详情见【4,IOC创建对象方式】

6.2,Set方式注入

  • 依赖:bean对象的创建依赖于容器
  • 注入:bean对象中的所有属性,由容器来注入
public class Student {
    private String name;
    private Address address;
    private String[] books;
    private List hobbys;
    private Map card;
    private Set games;
    private String wife;
    private Properties info;
		// getter、setter、toString略
}

student.xml

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

    
        
        
        
        
        
        
            
                
                
            
        
        
        
            
                java并发
                集群
                jvm Hotspot
            
        
  
        
            
                打游戏
                听歌
                骑车
            
        
        
            
                lol
                wow
                原神
            
        
        
            
        
        
            
                jdbc.driver.className=com.mysql.jdbc.Driver
                jdbc.url=jdbc:mysql://localhost:3306/mydb
            
        
    
    
        
    

输出:

Student{name='wanyu', address=Address{location='杭州'}, books=[java并发, 集群, jvm Hotspot], hobbys=[打游戏, 听歌, 骑车], card={phone=123456, idCard=42061111}, games=[lol, wow, 原神], wife='', info={jdbc.url=jdbc:mysql://localhost:3306/mydb, jdbc.driver.className=com.mysql.jdbc.Driver}}

6.3,扩展方式注入

p-namespace and c-namespace injection

p-namespace(set方法)



    


c-namespace(构造方法)



    


注意点:p 和 c命名空间注入需要额外应用xml约束

6.4,作用域

bean scope

image-20220111221831448

样例:







其他的request、session、application等在下个springMVC学习(挖坑)

7,自动装配

  • Spring满足bean依赖一种方式
  • Spring会在上下文中自动寻找,并自动给bean装配属性

在spring中有三种装配方式:①xml中显式配置;②java中显式配置;③隐式的自动装配bean

7.1,原始的显示装配



    
    

    
        
        
        
    


7.2,byType & byName



    

  • byName时,需要保证所有bean的id唯一,并且这个bean需要和自动注入属性值一致
  • byType时,需要保证所有bean的class唯一,并且这个bean需要和自动注入属性值一致

7.3,使用注解自动装配

jdk1.5支持注解,spring2.5支持注解装配

image-20220111225726107

前提条件:

①导入约束(context约束);

②配置注解的支持; 百度百科-spring框架

2,Spring官网

3,Spring源码下载地址

4,spring-github地址

5,遇见狂神说-spring5技术讲解

6,Spring IOC本质分析