相关推荐recommended
Spring系列一:spring的安装与使用
作者:mmseoamin日期:2023-12-05

文章目录

  • 💞 官方资料
    • 🍊Spring5下载
    • 🍊文档介绍
    • 💞Spring5
      • 🍊内容介绍
      • 🍊重要概念
      • 💞快速入门
        • 🍊Spring操作演示
        • 🍊类加载路径
        • 🍊Debug配置
        • 🍊Spring容器结构剖析
        • 💞实现简单基于XML配置程序
          • 🍊Spring原生容器结构梳理
          • 🍊作业布置
          • 💞基于XML配置Bean
            • 💖通过类型获取bean
            • 💖通过指定构造器配置bean
            • 💖通过p名称空间配置bean
            • 💖通过ref配置bean
            • 💖通过内部bean配置属性

              💞 官方资料

              Spring系列一:spring的安装与使用,在这里插入图片描述,第1张

              🍊Spring5下载

              1. 进入官网: https://spring.io/
              2. 这里的版本是Spring5 (Spring框架就是一系列jar包. 即引入jar包, 就可以使用spring)

                Spring系列一:spring的安装与使用,在这里插入图片描述,第2张

              3. 进入Spring5的github(Spring本身也是GitHub的开源项目)

                Spring系列一:spring的安装与使用,在这里插入图片描述,第3张下拉找到Access to Binaries, 进入Spring Framework Artifacts

              Spring系列一:spring的安装与使用,在这里插入图片描述,第4张进入到Spring的仓库(这里有Spring的各个版本的jar包)

              Spring系列一:spring的安装与使用,在这里插入图片描述,第5张具体路径 snapshot->org->springframework->spring

              Spring系列一:spring的安装与使用,在这里插入图片描述,第6张下载网址 https://repo.spring.io/artifactory/snapshot/org/springframework/spring/

              Spring系列一:spring的安装与使用,在这里插入图片描述,第7张Spring系列一:spring的安装与使用,在这里插入图片描述,第8张这里博主已把所有资源上传, 无需再去官网下载, 资料如下

              Spring系列一:spring的安装与使用,在这里插入图片描述,第9张

              各个jar包的含义

              Spring系列一:spring的安装与使用,在这里插入图片描述,第10张

              🍊文档介绍

              在线文档https://docs.spring.io/spring-framework/reference/
              离线文档spring-framework-5.3.8\docs\reference\html\index.html
              离线APIspring-framework-5.3.8\docs\javadoc-api\index.html

              💞Spring5

              🍊内容介绍

              Spring核心学习内容 IOC, AOP, jdbcTemplate, 声明式事务

              1. IOC: 控制反转, 可以管理java对象
              2. AOP: 切面编程
              3. JDBCTemplate: 是spring提供的一套访问数据库的技术. 应用性强, 相对好理解
              4. 声明式事务: 基于ioc/aop实现事务管理
              5. IOC, AOP 是重点同时是难点, 需要时间理解

              🍊重要概念

              1. Spring可以整合其它的框架(解读: Spring是管理框架的框架)

              2. Spring有两个核心的概念: IOC 和 AOP

              3. IOC [Inversion Of Control 反转控制]

              4. 传统的开发模式[JDbcUtils / 反射], 程序------>环境 //程序读取环境配置, 然后自己创建对象

                以连接到数据库为例

                程序员编写程序, 在程序中读取配置信息

                创建对象, 使用对象完成任务

              5. Spring方式

                Spring根据配置文件xml / 注解, 创建对象, 并放入到容器(ConcurrentHashMap). 并且可以完成对象之间的依赖

                当需要使用某个对象实例的时候, 就直接从容器中获取即可

                这样程序员可以更加关注如何使用对象完成相应的业务(以前是new -> 现在是注解 / 配置)

              6. DI - Dependency Injection依赖注入, 可以理解成是IOC的别称

                Spring最大的价值是 通过配置, 给程序员提供需要使用的对象web层[Servlet (Action/Controller)/ Service / Dao / JavaBean(entity)]对象

                这是核心价值所在, 也是ioc的具体体现, 实现解耦

              💞快速入门

              🍊Spring操作演示

              需求: 通过Spring的方式[配置文件], 获取JavaBean-Monster的对象, 并给该对象的属性赋值, 输出该对象的信息

              1. 下载Spring5开发包, Spring5开发包资源博主已上传
              2. 创建Java工程, Spring5

                Spring系列一:spring的安装与使用,在这里插入图片描述,第11张

              3. 新建lib目录, 引入开发Spring5的基本包

                Spring系列一:spring的安装与使用,在这里插入图片描述,第12张

              4. 创建JavaBean, 一定要有无参构造器. Spring底层反射创建对象时, 需要使用
              package com.zzw.spring.bean;
              public class Monster {
                  private String monsterId;
                  private String name;
                  private String skill;
                  //无参构造器: Spring底层反射创建对象时, 需要使用
                  public Monster() {
                  }
              	//有参构造器, setter, getter, toString()
              }
              
              1. src目录下: 新建一个容器配置文件beans.xml

                Spring系列一:spring的安装与使用,在这里插入图片描述,第13张

                创建好之后, 右上角进行配置, 不难

                Spring系列一:spring的安装与使用,在这里插入图片描述,第14张

              说明: xmlns表示xml namespace, 即xml命名空间

              
              
                  
                  
                      
                      
                      
                  
              
              

              测试

              package com.zzw.spring.test;
              public class SpringBeanTest {
                  @Test
                  public void getMonster() {
                      //解读
                      //1.创建容器 ApplicationContext
                      //2.该容器和容器配置文件关联
                      //3.习惯用接口的形式接收
                      ApplicationContext ioc =
                              new ClassPathXmlApplicationContext("beans.xml");
                      //3.通过getBean获取对应的对象
                      //  默认返回的是Object, 但是运行类型是Monster
                      //Object monster01 = ioc.getBean("monster01");
                      Monster monster01 = (Monster) ioc.getBean("monster01");
                      //4.输出
                      System.out.println("monster01" + monster01 + ", monster01运行类型" + monster01.getClass());
                      System.out.println("monster01" + monster01 + ", 属性name=" + monster01.getName() + ", monsterId="+ monster01.getMonsterId());
                      //5.也可以在获取的时候, 直接指定Class类型, 可以再次获取
                      Monster monster011 = ioc.getBean("monster01", Monster.class);
                      System.out.println("monster011=" + monster011);
                      System.out.println("monster011.name=" + monster011.getName());
                      
                      System.out.println("ok~~~");
                  }
              }
              

              🍊类加载路径

              解释类加载路径

              ApplicationContext ioc = new ClassPathXmlApplicationContext(“beans.xml”);

              //验证类加载路径
              @Test
              public void classPath() {
                  File file = new File(this.getClass().getResource("/").getPath());
                  //看到类的加载路径
                  System.out.println("file=" + file);
              }
              

              Spring系列一:spring的安装与使用,在这里插入图片描述,第15张

              🍊Debug配置

              小技巧分享

              Spring系列一:spring的安装与使用,在这里插入图片描述,第16张

              Spring系列一:spring的安装与使用,在这里插入图片描述,第17张

              Spring系列一:spring的安装与使用,在这里插入图片描述,第18张

              Spring系列一:spring的安装与使用,在这里插入图片描述,第19张

              Spring系列一:spring的安装与使用,在这里插入图片描述,第20张

              🍊Spring容器结构剖析

              判断是否是懒加载: 是事先创建好, 还是等到用户使用的时候再创建.

              lazyInit: false. 说明beans.xml中对象的创建不是懒加载.

              用Debug的方式, 看一下Spring容器的处理机制

              Spring系列一:spring的安装与使用,在这里插入图片描述,第21张

              ioc->beanFactory->beanDefinitionMap

              Spring系列一:spring的安装与使用,在这里插入图片描述,第22张

              beanDefinitionMap / table

              Spring系列一:spring的安装与使用,在这里插入图片描述,第23张

              index=217

              Spring系列一:spring的安装与使用,在这里插入图片描述,第24张

              table / propertyValues

              Spring系列一:spring的安装与使用,在这里插入图片描述,第25张

              beanFactory->singletonObjects

              Spring系列一:spring的安装与使用,在这里插入图片描述,第26张

              singletonObjects / table

              Spring系列一:spring的安装与使用,在这里插入图片描述,第27张

              beanFactory / beanDefinitionNames

              Spring系列一:spring的安装与使用,在这里插入图片描述,第28张

              题目: 查看容器注入了哪些bean对象, 输出bean的id

              String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
              for (String beanDefinitionName : beanDefinitionNames) {
                  System.out.println("beanDefinitionName=" + beanDefinitionName);
              }
              

              💞实现简单基于XML配置程序

              需求说明

              1. 自己写一个简单的Spring容器, 通过读取beans.xml, 获取第1个JavaBean: Monster的对象, 并给该对象的属性赋值, 放入到容器中, 并输出该对象信息
              2. 也就是说, 不使用Spring原生框架, 我们自己简单模拟实现
              3. 了解Spring容器的简单机制

              思路分析

              Spring系列一:spring的安装与使用,在这里插入图片描述,第29张

              实现

              引入dom4j-1.6.1.jar包

              ZzwApplicationContext.java

              package com.zzw.spring.zzwapplicationcontext;
              /**
               * @author 赵志伟
               * @version 1.0
               * 1.这个程序用于实现Spring的一个简单容器机制
               * 2.后面还会详细实现
               * 3.这里我们实现如何将beans.xml文件进行解析, 并生成对象, 放入容器中
               * 4.提供一个方法 getBean(id) 返回对应的对象
               * 5.这里就是一个开胃小点心, 理解Spring容器的机制
               */
              @SuppressWarnings({"all"})
              public class ZzwApplicationContext {
                  private ConcurrentHashMap singletonObjects = new ConcurrentHashMap<>();
                  //构造器
                  //接收一个容器的配置文件 比如 beans.xml, 该文件默认在src目录下
                  public ZzwApplicationContext(String iocBeanXmlFile) throws Exception {
                      //1.得到类加载路径:
                      // /D:/idea_project/zzw_spring/spring/out/production/spring/
                      String path = this.getClass().getResource("/").getPath();
                      //2.创建解析器
                      SAXReader reader = new SAXReader();
                      //3.得到document对象
                      Document document = reader.read(new File(path + iocBeanXmlFile));
                      //4.获取rootElement
                      Element rootElement = document.getRootElement();
                      //5.得到第1个bean-monster01
                      Element bean = (Element) rootElement.elements("bean").get(0);
                      //6.获取第一个bean-monster01的相关属性 => beanDefinitionMap
                      String id = bean.attributeValue("id");
                      String ClassFullPath = bean.attributeValue("class");
                      List properties = bean.elements("property");
                      //这里不再遍历, 直接获取
                      Integer monsterId = Integer.parseInt(properties.get(0).attributeValue("value"));
                      String name = properties.get(1).attributeValue("value");
                      String skill = properties.get(2).attributeValue("value");
                      //7.使用反射创建对象 => 回顾反射机制
                      Class aClass = Class.forName(ClassFullPath);
                      //这里instance就是Monster对象
                      Monster o = (Monster) aClass.newInstance();
                      //给o对象通过反射来赋值 => 这里先简化
                      o.setMonsterId(monsterId);
                      o.setName(name);
                      o.setSkill(skill);
                      //8.将创建好的对象放入到singletonObjects
                      singletonObjects.put(id, o);
                  }
                  public Object getBean(String id) {
                      //这里可以再处理一下
                      return singletonObjects.get(id);
                  }
              }
              

              测试 ZzwApplicationContextTest

              package com.zzw.spring.zzwapplicationcontext;
              public class ZzwApplicationContextTest {
                  public static void main(String[] args) throws Exception {
                      ZzwApplicationContext ioc = new ZzwApplicationContext("beans.xml");
                      Monster monster01 = (Monster) ioc.getBean("monster01");
                      System.out.println("monster01=" + monster01);
                      System.out.println("monster01.name=" + monster01.getName());
                      System.out.println("ok~");
                  }
              }
              

              🍊Spring原生容器结构梳理

              Spring系列一:spring的安装与使用,在这里插入图片描述,第30张

              🍊作业布置

              在beans.xml中, 注入两个Monster对象, 但是不指定id, 运行会不会报错?

              如果不会报错, 如果知道id, 并获取Monster对象.

              1. 不会报错, 会正常运行
              2. 系统会默认分配id. 分配id的规则是: 全类名#0, 全类名#1 这样的规则来分配id的. 例如 com.zzw.spring.bean.Monster#0, com.zzw.spring.bean.Monster#1
              3. 通过debug方式来查看

                Spring系列一:spring的安装与使用,在这里插入图片描述,第31张

              public class homework01 {
                  @Test
                  public void getMonster() {
                      //1.创建容器, 习惯用接口的形式接收
                      ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
                      Monster monster1 = ioc.getBean("com.zzw.spring.bean.Monster#0", Monster.class);
                      System.out.println("monster1=" + monster1);
                      Monster monster2 = ioc.getBean("com.zzw.spring.bean.Monster#1", Monster.class);
                      System.out.println("monster2=" + monster2);
                      System.out.println("ok~");
                  }
              }
              

              创建一个Car类, 要求

              1. 创建ioc容器文件(配置文件), 并配置一个Car对象(bean).
              2. 通过java程序到ioc容器获取该bean对象, 并输出
              public class Car {
                  private Integer id;
                  private String name;
                  private Double price;
                  public Car() {
                      System.out.println("car对象 无参构造器被执行");
                  }
                  //有参构造器, setter, getter, toString()
              

              beans1.xml

              
              
                  
                  
                      
                      
                      
                  
              
              
              public class homework02 {
                  public static void main(String[] args) {
                      //1.创建容器对象
                      ApplicationContext ioc = new ClassPathXmlApplicationContext("beans1.xml");
                      Car car01 = ioc.getBean("car01", Car.class);
                      System.out.println("car01=" + car01);
                      System.out.println("car01.name=" + car01.getName());
                      System.out.println("ok~");
                  }
              }
              

              💞基于XML配置Bean

              💖通过类型获取bean

              案例: 通过spring的ioc容器, 获取一个bean对象, 获取方式: 按类型.

              
              
                  
                  
                  
                  
              
              

              演示通过bean的类型获取对象

              @Test
              public void getBeanByType() {
                  ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
                  //直接传入class对象/类型
                  Monster bean = ioc.getBean(Monster.class);
                  System.out.println("bean=" + bean);
              }
              

              细节

              按照类型获取bean, 要求ioc容器中的同一个类的bean只能有一个, 否则会抛出异常 NoUniqueBeanDefinationException

              这种方式的应用场景: 比如XxxAction / Servlet / Controller, 或XxxService在一个线程中只需要一个对象实例(单例)的情况

              在容器配置文件(比如beans.xml)中给属性赋值. 底层是通过setter方法完成的. 所以需要提供setter方法.

              💖通过指定构造器配置bean

              
              
              
                 
                 
                 
              
              
                 
                 
                 
              
              
                 
                 
                 
              
              

              演示通过构造器来设置属性

              @Test
              public void setBeanByConstructor() {
                  ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
                  Monster monster03 = ioc.getBean("monster03", Monster.class);
                  System.out.println("monster03=" + monster03);
              }
              

              Spring系列一:spring的安装与使用,在这里插入图片描述,第32张

              Spring系列一:spring的安装与使用,在这里插入图片描述,第33张

              通过index属性来区分是第几个参数;

              通过type属性来区分是什么类型(按照顺序, 这是可以的)

              💖通过p名称空间配置bean

              xmlns:p=“http://www.springframework.org/schema/p”

              
              
              

              演示通过p名称空间来设置属性

              public class SpringBeanTest {
                  @Test
                  public void setBeanByP() {
                      ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
                      Monster monster06 = ioc.getBean("monster06", Monster.class);
                      System.out.println("monster06=" + monster06);
                  }
              }
              

              💖通过ref配置bean

              引用注入其它bean对象

              在spring的ioc容器, 可以通过ref来实现bean对象的相互引用[ref全称: reference]

              
              
              
              
                  
              
              
              package com.zzw.spring.service;
              public class MemberServiceImpl {
                  private MemberDaoImpl memberDao;
                  public MemberDaoImpl getMemberDao() {
                      return memberDao;
                  }
                  public void setMemberDao(MemberDaoImpl memberDao) {
                      this.memberDao = memberDao;
                  }
                  public void add() {
                      System.out.println("MemberServiceImpl add方法被调用...");
                      memberDao.add();
                  }
              }
              
              package com.zzw.spring.dao;
              public class MemberDaoImpl {
                  public MemberDaoImpl() {
                      System.out.println("MemberDaoImpl 构造器...");
                  }
                  public void add() {
                      System.out.println("MemberDaoImpl add方法被执行");
                  }
              }
              

              通过ref来设置bean属性

              public class SpringBeanTest {
                  @Test
                  public void setBeanByRef() {
                      ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
                      MemberServiceImpl memberService = ioc.getBean("memberService", MemberServiceImpl.class);
                      memberService.add();
                  }
              }
              

              Spring系列一:spring的安装与使用,在这里插入图片描述,第34张

              💖通过内部bean配置属性

              引用/注入内部bean对象

              在spring的ioc容器, 可以直接配置内部bean对象

              
              
                  
                  
                      
                  
              
              

              通过内部bean, 设置属性

              public class SpringBeanTest {
                  @Test
                  public void setBeanByPro() {
                      ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
                      MemberServiceImpl memberService2 = ioc.getBean("memberService2", MemberServiceImpl.class);
                      memberService2.add();
                  }
              }
              

              Spring系列一:spring的安装与使用,在这里插入图片描述,第35张

              下乘: Spring系列二:基于XML配置bean