javaee之spring1

news2024/11/17 10:03:46

什么是Spring

一、Spring的优势

二、Spring的体系结构

先说一下从什么位置去下载Spring的源码

进入Spring官网,找到Spring Framework框架

 

点进去之后,找到如下位置,继续点击

 

 进去之后,继续下拉,找到下面这个位置点进去

 

进去之后继续点击 

 

 找到上面这个位置之后,就按照层级目录,继续点下去

 

然后你就可以下载你想要的版本了

 具体的体系结构 

 Ioc的概念和作用

一、分析一下程序之间的耦合性

首先我们来创建一个maven项目,然后里面写一个Jdbc的连接程序,它需要一个mysql的连接jar包

导入到pom.xml里面

pom.xml

 

上面程序的运行成功依赖于com.mysql.jdbc.Driver()这个对象 ,这个就是耦合,上面如果没有引入mysql的jar包,就会编译期给我们报错

耦合:程序间的依赖关系,这里面就包括了类之间的依赖与方法之间的依赖

解耦:降低程序之间的依赖关系

在实际开发中:编译期不依赖,运行时才依赖

上面代码我们就可以做出一些修改

那么解耦的思路:

        第一步:使用户反射来创建对象,而避免使用new关键字

        第二步:通过读取配置文件来获取要创建的对象全限定类名

 二、曾经代码中的问题分析

首先我们来看一个模拟的账户查询业务代码

先来看一下dao层

做了一很简单的事儿,就死调用了数据库保存了账户信息

 下面进入到service层里面看一下

 下面在进入到业务层里面

上面这种各个文件的依赖关系啊,会让程序的耦合性非常差,其实就是太依赖了嘛

先来看一下依赖的这两个对象

 

你说这两个对象是不是都可以通过工厂模式来创建

所以我们来创建一个工厂来产生这两个对象的,我们都知道,工厂模式,是利用反射来创建对象的,下面来具体说一下如何创建

先来说一下实现原理

先来做这个配置文件

 

下面就是在工厂里面引入配置文件,然后把对象封装到集合里面,然后每次根据传入的key,来获取响应的对象

BeanFactory.java

package com.pxx.factory;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 一个创建Bean对象的工厂
 * Bean:在计算机里面就是组件的意思
 * JavaBean: 用java写的可重用组件 一般理解为一个实体类
 * 但是JavaBean的概念大于了实体类
 *
 * 下面说一下创建servicea对象和dao对象的核心步骤
 * 1.需要一个配置文件来配置service和dao的全限定类名,这里也就是说不要写死
 * 2.通过读取配置文件的配置内容,反射创建对象
 *
 */
public class BeanFactory {
    //这个后面引入配置文件信息
    private static Properties prop;

    //把对象引入到一个map集合里面
    private static Map<String,Object> objectMap;

    static {
        try {
            //上面两个属性必须new出来
            prop = new Properties();
            objectMap = new HashMap<String, Object>();
            InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
            //信息加载到Properties类里面
            prop.load(in);
            //下面就是循环拿到key,利用value进行newInstance
            Enumeration e = prop.keys();
            while (e.hasMoreElements()) {
                String key = (String) e.nextElement();//这个会拿到key
                String value = prop.getProperty(key);//根据key来得到值
                Object o = Class.forName(value).newInstance();
                //然后把对象添加到集合里面
                objectMap.put(key, o);
            }
        } catch (Exception e) {
            //如果出错,直接error,程序失败
            throw new ExceptionInInitializerError("初始化失败");
        }
    }

    //需要根据配置文件的参数来获得相应对象
    //name-》{accountService,accountDao}
    public Object getObject(String name) {
        //集合里面封装了两个对象
        return objectMap.get(name);
    }
}

现在我们去修改业务层的调用

 然后去修改表现层的代码

运行结果:

 

  分析一下上面的代码,一定是单例设计

 

 一张图来直接说明

 单例设计的有点就在于,内存不会开辟那么多的对象,提高效率

下面来说一下Ioc的概念与作用

根据上面的代码,之前我们是这样来生产一个对象

 

也就是说应用层与对象直接打交道。但是它现在放弃了这种方式,按照如下方式来创建了一个对象

 

 把创建对象的工作交给了框架

这种被动接收的方式获取对象的思想就是控制反转,它是Spring框架的核心之一

使用Spring的IOC解决程序耦合 

先来说一下Spring的开发包

 进入到dist里面

 特别说明:

我们用的是Spring5.0的版本

可以从这个位置去查询一些相关信息

  

下面我们来实现Account账户的解耦。

1.导入需要的spring的jar包,然后整一个xml文档,这个名字只要是英文就行

 这个spring的相关jar包就做出来了,看一下右边

 

这个xml文档约束,就可以去

 

点进去这个位置去找

 

直接复制引入

 

 然后去到表现层里面

运行结果:

 

 下面来说一下ApplicationContext这个类

看一下结构

 右键选择它的实现类

 我们用到的就是下面这个实现类

我们直接拿一张图放过来

 

 BeanFactory 和 和 ApplicationContext 的区别

 ApplicationContext接口实现类:

spring中利用BeanFactory来实现对象的创建:

这个对象的创建内部需要传入一个资源文件对象

 

 IOC中bean 标签和管理对象细节

一、创建Bean的三种方式

第一种:通过默认构造函数创建对象

第二种: 使用普通工厂的方法创建对象(使用某个类中的方法创建对象,存入spring容器)

也就是调用下面类中的方法创建一个对象

其实得到IAccountService的对象方法没有做啥改动 ,只是内部获取对象的方式发生了变化

第三种使用工厂当中的某个静态方法获取对象(使用某个类中的静态方法创建对象)

先来创建这个类与方法

 

 

三、bean的作用范围与生命周期

这里主要来演示一下单例和多例

说一下先在AccountServiceImpl里面做一个默认的构造函数,创建对象的时候会被调用,默认调用无参构造

 这里说一下我这配置的域是单例的,单例在什么时候创建对象

 我们在下面设置一个断点

 debug一运行,你看对象无参构造已经被调用了

 所以单例是在加载配置文件的时候就会被调用起来

Spring依赖注入

一、什么是依赖注入

 

二、依赖 注入的方式

 

构造函数注入

 

 把AccountDaoImpl.java做一些修改,这只是一个模拟过程,不代表实际业务

 上面就展示了通过构造函数需要封装的数据,下面是一个封装结果

上面就通过构造函数注入好了,下面来测试一下,很明显就是被调起来了嘛

 set注入

这里必须说一下set注入原理

然后在说一下它的使用方法 

 在使用set方法注入之前,一定要生成set方法

假如说这里我们把无参构造给注释起来

然后再去看一下 bean.xml里面的set配置

 客户端也看一下

然后调一下

 

报一堆错,这个其实就是说,没有去实例化一个AccountDaoImpl.java的一个对象,因为你把无参给注释掉了

现在打开

 

 

下面就来说复杂类型的注入与集合类型的注入

 

先来看一下AccountDaoImpl1.java

package com.pxx.dao.impl;

import com.pxx.dao.IAccountDao;

import java.util.*;

public class AccountDaoImpl1 implements IAccountDao {

    private String[] myStrs;
    private List<String> myList;
    private Set<String> mySet;
    private Map<String,String> myMap;
    private Properties myProps;

    public void setMyStrs(String[] myStrs) {
        this.myStrs = myStrs;
    }

    public void setMyList(List<String> myList) {
        this.myList = myList;
    }

    public void setMySet(Set<String> mySet) {
        this.mySet = mySet;
    }

    public void setMyMap(Map<String, String> myMap) {
        this.myMap = myMap;
    }

    public void setMyProps(Properties myProps) {
        this.myProps = myProps;
    }

    public void saveAccount() {
        System.out.println(Arrays.toString(myStrs));
        System.out.println(myList);
        System.out.println(mySet);
        System.out.println(myMap);
        System.out.println(myProps);
    }
}

去bean.xml里面配置一下

 运行结果:

 这里上一下bean.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- spring中的依赖注入
        依赖注入:
            Dependency Injection
        IOC的作用:
            降低程序间的耦合(依赖关系)
        依赖关系的管理:
            以后都交给spring来维护
        在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明
        依赖关系的维护:
            就称之为依赖注入。
         依赖注入:
            能注入的数据:有三类
                基本类型和String
                其他bean类型(在配置文件中或者注解配置过的bean)
                复杂类型/集合类型
             注入的方式:有三种
                第一种:使用构造函数提供
                第二种:使用set方法提供
                第三种:使用注解提供(明天的内容)
     -->


    <!--构造函数注入:
        使用的标签:constructor-arg
        标签出现的位置:bean标签的内部
        标签中的属性
            type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
            index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
            name:用于指定给构造函数中指定名称的参数赋值                                        常用的
            =============以上三个用于指定给构造函数中哪个参数赋值===============================
            value:用于提供基本类型和String类型的数据
            ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象

        优势:
            在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。
        弊端:
            改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。
    -->
    <bean id="now" class="java.util.Date"></bean>
  <bean id="accountDao" class="com.pxx.dao.impl.AccountDaoImpl">
         <constructor-arg name="name" value="张三"></constructor-arg>
        <constructor-arg name="age" value="25"></constructor-arg>
        <constructor-arg name="birthday" ref="now"></constructor-arg>
  </bean>

    <!--
        采用set方法注入
    -->
    <bean id="accountDao1" class="com.pxx.dao.impl.AccountDaoImpl">
        <property name="name" value="纠结伦"></property>
        <property name="age" value="21"></property>
        <property name="birthday" ref="now"></property>
    </bean>

    <!--
        复杂类型的注入、集合类型注入
    -->
    <bean id="accountDao2" class="com.pxx.dao.impl.AccountDaoImpl1">
        <property name="myStrs">
            <set>
                <value>张三</value>
                <value>王五</value>
                <value>李四</value>
            </set>
        </property>

        <property name="myList">
            <array>
                <value>list1</value>
                <value>list2</value>
                <value>list3</value>
            </array>
        </property>

        <property name="mySet">
            <list>
                <value>set1</value>
                <value>set2</value>
                <value>set3</value>
            </list>
        </property>

        <!--下面
        是map集合和Properties的对象自动注入
        -->
        <property name="myMap">
            <props>
                <prop key="map1">map1</prop>
                <prop key="map2">map2</prop>
            </props>
        </property>

        <property name="myProps">
            <map>
               <entry key="myProps1" value="张三"></entry>
               <entry key="myProps2" value="李四"></entry>
            </map>
        </property>
    </bean>


</beans>

这里的代码在spring1_copy_normal。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/111636.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

慕了,我要是早点看到这篇写 Kafka 的分区管理的文章就好了

Kafka可以将主题划分为多个分区&#xff08;Partition&#xff09;&#xff0c;会根据分区规则选择把消息存储到哪个分区中&#xff0c;只要如果分区规则设置的合理&#xff0c;那么所有的消息将会被均匀的分布到不同的分区中&#xff0c;这样就实现了负载均衡和水平扩展。另外…

可以做抽奖活动的微信小程序在哪里做_分享抽奖活动小程序制作步骤

越来越多的企业开始了解微信抽奖游戏的实用性和价值&#xff0c;因为用户更喜欢简单有趣的游戏抽奖方式&#xff0c;如大转盘、摇一摇、抢福袋、砸金蛋、摇一摇、刮刮卡等互动抽奖游戏。 如果企业想制作这种抽奖游戏&#xff0c;都倾向使用市场上的各种抽奖制作软件&#xff0c…

(Java)车厢重组

车厢重组一、题目描述二、输入格式三、输出格式四、样例&#xff08;1&#xff09;样例输入&#xff08;2&#xff09;样例输出五、正确代码六、思路一、题目描述 在一个旧式的火车站旁边有一座桥&#xff0c;其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最…

网络技术——网络运维工程师必会的网络知识(2)(详细讲解)

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 网络传输介质 信号分类和失真 双绞线分类&#xff1a; 双绞线…

非计算机专业,可以学好编程吗?

现在IT行业越来越火热&#xff0c;想要学习编程的人也越来越多。IT行业的薪资连续好几年赶超金融行业&#xff0c;位居行业之首&#xff0c;有太多人转行跨界&#xff0c;想要进入这个领域&#xff0c;那么作为初学者的你&#xff0c;是不是也很困惑&#xff0c;非科班&#xf…

Web入门开发【四】- 基础语言

欢迎来到霍大侠的小院&#xff0c;我们来学习Web入门开发的系列课程。 首先我们来了解下这个课程能学到什么&#xff1f; 1、你将可以掌握Web网站的开发全过程。 2、了解基础的HTML&#xff0c;CSS&#xff0c;JavaScript语言。 3、开发自己的第一个网站。 4、认识很多对编…

Java笔记之多线程(一)

文章目录前言一、什么是进程与线程&#xff1f;1.进程2.线程3.其他相关概念二、如何创建线程1.继承Thread类&#xff0c;重新run方法2.实现Runnable接口3.通过Callable和Future创建线程4. 继承Thread vs实现Runnable的区别三、用户线程和守护线程守护线程的使用设置成守护线程四…

【Python百日进阶-数据分析】Day137 - plotly旭日图:go.sunburst()实例

文章目录4.2 带有 go.Sunburst 的基本旭日图4.2.1 基本go.sunburst()旭日图4.2.2 带有重复标签的旭日图4.2.3 分支值4.2.4 大量切片4.2.5 控制旭日形扇区内的文本方向4.2.6 使用 uniformtext 控制文本字体大小4.2.7 具有连续色标的旭日图4.2.8 Dash中的go.sunburst()4.2 带有 g…

Android hilt 依赖注入使用详解

文章目录官方文档添加依赖初始化hiltMainActivity 使用共享类在 MainActivity 添加依赖注入ActivityScoped 作用域Singleton 作用域构造参数&#xff0c;添加 Context参数ApplicationContext、ActivityContext官方文档 https://developer.android.com/training/dependency-inj…

【Linux】缓冲区/磁盘inode/动静态库制作

目录 一、缓冲区 1、缓冲区的概念 2、缓冲区的意义 3、缓冲区刷新策略 4、同一份代码&#xff0c;打印结果不同 5、仿写FILE 5.1myFILE.h 5.2myFILE.c 5.3main.c 6、内核缓冲区 二、了解磁盘 1、磁盘的物理结构 2、磁盘的存储结构 2.1磁盘的定位 3、磁盘的抽象…

基于价值迭代求解迷宫寻路问题

摘 要 迷宫寻路是人工智能和计算机科学中一个经典的问题。它涉及在迷宫中找到一条从起点到终点的最短路径。这个问题可以用来模拟真实世界中的许多情况&#xff0c;例如机器人在工厂中自动导航&#xff0c;搜索引擎在网络中寻找信息&#xff0c;或者人类在城市中导航。 迷宫寻路…

【Javascript基础】--零基础--超详细且简洁的Javascript笔记--简介(01)

参考资料&#xff1a; 【现代Javascript教程】https://zh.javascript.info/ 【MDN】https://developer.mozilla.org/zh-CN/ 笔记仅作为学习交流载体&#xff0c;无任何商业或盈利目的 JavaScript 简介 了解 JavaScript 有什么特别之处&#xff0c;我们可以用它实现什么&#…

适合编程初学者的开源博客系统(Vue3+Element Plus版)

目标 为编程初学者打造入门学习项目&#xff0c;使用各种主流编程语言来实现。让想学编程的&#xff0c;一个都不落下。 上述基本涵盖了当前编程开发所有主流语言。 左侧为前端版本&#xff1a;安卓、iOS、鸿蒙、Flutter、Vue、uni-app、微信小程序。 右侧为服务器端版本&am…

YOLOV7学习记录之模型推理

前面我们学习了YOLOV7的训练过程&#xff0c;今天我们学习其推理过程&#xff0c;即模型预测&#xff1a;其包含损失函数计算&#xff0c;输出值解码&#xff0c;非极大值抑制&#xff0c;mAP计算等过程。 同时还介绍原始图像上绘制目标框等功能。 我们从predict.py文件开始&am…

【源码共读】Vite 项目自动添加 eslint 和 prettier

vite-pretty-lint库是一个为Vite创建的Vue或React项目初始化eslint和prettier的库。 该库的目的是为了让开发者在创建项目时&#xff0c;不需要手动配置eslint和prettier&#xff0c;而是通过vite-pretty-lint库来自动配置。 源码地址&#xff1a; vite-pretty-lintgithub1s…

设计模式 - 单例模式(一)

单例模式一 官方定义二 单例模式八种方式2.1 饿汉式&#xff08;静态常量&#xff09;代码案例案例分析2.2 饿汉式&#xff08;静态代码块&#xff09;代码案例案例分析2.3 懒汉式(线程不安全)代码案例案例分析2.4 懒汉式(线程安全&#xff0c;同步方法)代码案例案例分析2.5 懒…

数据要求说明书(GB856T——88)基于协同的在线表格forture-sheet

数据要求说明书 1引言 1.1编写目的 本份数据要求说明书详细的提供了系统中各个数据的流向&#xff0c;是设计数据库的关键所在。为以后的编码以及测试提供一份可靠的依据。 预期的读者&#xff1a;系统开发人员、系统测试人员、系统维护人员 1.2背景 待开发的数据库名称&a…

揭秘百度智能测试在测试定位领域的实践

以前&#xff0c;我们介绍了测试活动测试输入、测试执行、测试分析、测试定位和测试评估五个步骤中测试输入、执行、分析、评估的智能化研究和实践&#xff0c;本文重点介绍测试定位环节的智能化实践。 测试定位的主要作用是在构建失败或问题发生后&#xff0c;快速给出产生该现…

机器学习之回归

回归算法 线性回归 求解线性回归方法 正规方程梯度下降 迭代 API sklearn.linear_model.LinearRegression 正规方程优化fit_intercept 是否计算偏置量&#xff0c;没有的化经过原点属性 coef_ 回归系数intercept_ 偏置量 sklearn.linear_model.SGDRegressor 使用随机梯度…

转行了!文科生转程序员的外包工作经历分享

01 种子 我是一名文科生&#xff0c;法律专业&#xff0c;武汉某 211 &#xff0c;入这行纯属巧合。 大三下半年&#xff0c;大家纷纷准备秋招&#xff0c;我去校园招聘会上溜达了一圈&#xff0c;好奇而去&#xff0c;丧气而归。 或许是因为大学三年过得太过安逸(宅在宿舍打…