【spring】第一篇 IOC和DI入门案例

Spring到底是如何来实现IOC和DI的,那接下来就通过一些简单的入门案例,来演示下具体实现过程。

目录

前期准备

一、IOC入门案例

思路分析

代码实现

二、DI入门案例

思路分析

代码实现

总结


前期准备

使用IDEA创建Maven项目,首先需要配置好Maven,新建一个Maven项目。

一、IOC入门案例

思路分析

(1)Spring是使用容器来管理bean对象的,那么管什么?

  • 主要管理项目中所使用到的类对象,比如(Service和Dao)

(2)如何将被管理的对象告知IOC容器?

  • 使用配置文件

(3)被管理的对象交给IOC容器,要想从容器中获取对象,就先得思考如何获取到IOC容器?

  • Spring框架提供相应的接口

(4)IOC容器得到后,如何从容器中获取bean?

  • 调用Spring框架提供对应接口中的方法

(5)使用Spring导入哪些坐标?

  • 用别人的东西,就需要在pom.xml添加对应的依赖

代码实现

(1)创建Maven项目,在pom.xml 添加Spring的依赖jar包,

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>

(2)创建BookService,BookServiceImpl,BookDao和BookDaoImpl四个类,

目录如下:

package com.water.dao;

public interface BookDao {
  public void save();
}
package com.water.dao.impl;

import com.water.dao.BookDao;

public class BookDaoImpl implements BookDao {
  public void save() {
    System.out.println("book dao save ...");
  }
}
package com.water.server;

public interface BookService {
  public void save();
}
package com.water.server.impl;

import com.water.dao.BookDao;
import com.water.dao.impl.BookDaoImpl;
import com.water.server.BookService;

public class BookServiceImpl implements BookService {
  private BookDao bookDao = new BookDaoImpl();
  public void save() {
    System.out.println("book service save ...");
    bookDao.save();
  }
}

(3)resources下添加spring配置文件applicationContext.xml,并完成bean的配置

<?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标签标示配置bean
    	id属性标示给bean起名字
    	class属性表示给bean定义类型
	-->
    <bean id="bookDao" class="com.water.dao.impl.BookDaoImpl"></bean>
    <bean id="bookService" class="com.water.server.impl.BookServiceImpl"></bean>
</beans>

(4)首先获取IOC容器,使用Spring提供的接口完成IOC容器的创建,创建App类,编写main方法。然后,从容器中获取对象进行方法调用。

package com.water;

import com.water.dao.BookDao;
import com.water.server.impl.BookService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App 
{
    public static void main( String[] args ) {
        // 获取IOC容器
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 获取bean
        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        bookDao.save();

        BookService bookService = (BookService) ctx.getBean("bookService");
        bookService.save();
    }
}

运行代码,测试结果为:

Spring的IOC入门案例已经完成,但是在BookServiceImpl的类中依然存在BookDaoImpl对象的new操作,它们之间的耦合度还是比较高,这块该如何解决,就需要用到下面的DI:依赖注入

二、DI入门案例

思路分析

(1)要想实现依赖注入,必须要基于IOC管理Bean

  • DI的入门案例要依赖于前面IOC的入门案例

(2)Service中使用new形式创建的Dao对象是否保留?

  • 需要删除掉,最终要使用IOC容器中的bean对象

(3)Service中需要的Dao对象如何进入到Service中?

  • 在Service中提供方法,让Spring的IOC容器可以通过该方法传入bean对象

(4)Service与Dao间的关系如何描述?

  • 使用配置文件

代码实现

(1)在BookServiceImpl类中,删除业务层中使用new的方式创建的dao对象 。在BookServiceImpl类中,为BookDao提供setter方法。

package com.water.server.impl;

import com.water.dao.BookDao;
import com.water.dao.impl.BookDaoImpl;
import com.water.server.BookService;

public class BookServiceImpl implements BookService {
  //删除业务层中使用new的方式创建的dao对象
//  private BookDao bookDao = new BookDaoImpl();
  private BookDao bookDao;

  public void save() {
    System.out.println("book service save ...");
    bookDao.save();
  }

  // 为属性提供setter方法
  public void setBookDao(BookDao bookDao) {
    this.bookDao = bookDao;
  }
}

(2)在配置文件中添加依赖注入的配置,

  • name="bookDao"中bookDao的作用是让Spring的IOC容器在获取到名称后,将首字母大写,前面加set找对应的setBookDao()方法进行对象注入

  • ref="bookDao"中bookDao的作用是让Spring能在IOC容器中找到id为bookDao的Bean对象给bookService进行注入

<?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标签标示配置bean
    	id属性标示给bean起名字
    	class属性表示给bean定义类型
	-->
    <bean id="bookDao" class="com.water.dao.impl.BookDaoImpl"></bean>
    <bean id="bookService" class="com.water.server.impl.BookServiceImpl">
        <!--配置server与dao的关系-->
        <!--property标签表示配置当前bean的属性
        		name属性表示配置哪一个具体的属性
        		ref属性表示参照哪一个bean
		-->
        <property name="bookDao" ref="bookDao"></property>
    </bean>
</beans>

(4)运行,测试结果为:

补充:bean基础配置

(1)bean的基础配置

对于bean的基础配置,在前面的案例中已经使用过:

<bean id="" class=""/>

其中,bean标签的功能、使用方式以及id和class属性的作用,我们通过一张图来描述下

(2)bean的别名配置

(3)bean的作用范围

在Spring配置文件中,配置scope属性来实现bean的非单例创建,使用bean的scope属性可以控制bean的创建是否为单例:

  • singleton默认为单例
  • prototype为非单例

介绍完scope属性以后,我们来思考几个问题:

1)为什么bean默认为单例?

bean为单例的意思是在Spring的IOC容器中只会有该类的一个对象。bean对象只有一个就避免了对象的频繁创建与销毁,达到了bean对象的复用,性能高

2)bean在容器中是单例的,会不会产生线程安全问题?

  • 如果对象是有状态对象,即该对象有成员变量可以用来存储数据的,因为所有请求线程共用一个bean对象,所以会存在线程安全问题。

  • 如果对象是无状态对象,即该对象没有成员变量没有进行数据存储的,因为方法中的局部变量在方法调用完成后会被销毁,所以不会存在线程安全问题。

3)哪些bean对象适合交给容器进行管理?

  • 表现层对象

  • 业务层对象

  • 数据层对象

  • 工具对象

4)哪些bean对象不适合交给容器进行管理?

封装实例的域对象,因为会引发线程安全问题,所以不适合。

总结

通过前面两个案例,我们已经学习了bean如何定义配置DI如何定义配置以及容器对象如何获取的内容。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linux进阶的一些操作以及知识点------习题集(实践)

请创建以你姓名全拼的用户luwenhua&#xff0c;将其设置为免密登录&#xff0c;切换到luwenhua用户&#xff0c;打开终端&#xff0c;完成以下操作 &#xff08;一&#xff09;bash脚本基础练习 1&#xff09;第一题&#xff1a;请在终端里定义两个用户变量num120&#xff0c…

来自大厂硬盘的降维打击!当希捷酷玩520 1TB SSD卷到369,请问阁下该怎么应对?

来自大厂硬盘的降维打击&#xff01;当希捷酷玩520 1TB SSD卷到369&#xff0c;请问阁下该怎么应对&#xff1f; 哈喽小伙伴们好&#xff0c;我是Stark-C~ 今年4月份的时候因为电脑上的游戏盘突然挂掉&#xff0c;为了性价比选购了希捷酷玩520 1TB SSD&#xff0c;同时我也是…

中国历年肥料进口数量统计报告

数据来源于国家统计局&#xff0c;为1991年到2021年我国每年肥料进口数量统计。 2021年&#xff0c;我国进口肥料909万吨&#xff0c;比上年减少151万吨。 数据统计单位为&#xff1a;万吨 数据说明&#xff1a; 数据来源于国家统计局&#xff0c;为海关进出口统计数 我国肥料…

网络网络层

data: 2024/5/25 14:02:20 周六 limou3434 叠甲&#xff1a;以下文章主要是依靠我的实际编码学习中总结出来的经验之谈&#xff0c;求逻辑自洽&#xff0c;不能百分百保证正确&#xff0c;有错误、未定义、不合适的内容请尽情指出&#xff01; 文章目录 1.协议结构2.封装分离3.…

SpringBoot与MyBatis零XML配置集成(附源码)

源代码先行&#xff1a; Gitee本文介绍的完整仓库&#xff1a;https://gitee.com/obullxl/ntopic-bootGitHub本文介绍的完整仓库&#xff1a;https://github.com/obullxl/ntopic-boot 背景介绍 在Java众多的ORM框架里面&#xff0c;MyBatis是比较轻量级框架之一&#xff0c;…

【JavaEE进阶】——MyBatis操作数据库 (#{}与${} 以及 动态SQL)

目录 &#x1f6a9;#{}和${} &#x1f388;#{} 和 ${}区别 &#x1f388;${}使用场景 &#x1f4dd;排序功能 &#x1f4dd;like 查询 &#x1f6a9;数据库连接池 &#x1f388;数据库连接池使⽤ &#x1f6a9;MySQL开发企业规范 &#x1f6a9;动态sql &#x1f388…

PCIe总线-事物层之TLP路由介绍(七)

1.概述 下图是一个PCIe总线系统示意图。此时RC发出一个TLP&#xff0c;经过Switch访问EP&#xff0c;TLP的路径为红色箭头所示。首先TLP从RC的下行OUT端口发出&#xff0c;Switch的上行IN端口接收到该TLP后&#xff0c;根据其路由信息&#xff0c;将其转发到Switch的下行OUT端…

Vue.js 动态组件与异步组件

title: Vue.js 动态组件与异步组件 date: 2024/6/2 下午9:08:50 updated: 2024/6/2 下午9:08:50 categories: 前端开发 tags:Vue概览动态组件异步加载性能提升路由管理状态控制工具生态 第1章 Vue.js 简介 1.1 Vue.js 概述 Vue.js 是一个渐进式的JavaScript框架&#xff0c;…

docker以挂载目录启动容器报错问题的解决

拉取镜像&#xff1a; docker pull elasticsearch:7.4.2 docker pull kibana:7.4.2 创建实例&#xff1a; mkdir -p /mydata/elasticsearch/configmkdir -p /mydata/elasticsearch/dataecho "http.host: 0.0.0.0" >> /mydata/elasticsearch/config/elasti…

深入解析Java中List和Map的多层嵌套与拆分

深入解析Java中List和Map的多层嵌套与拆分 深入解析Java中List和Map的多层嵌套与拆分技巧 &#x1f4dd;摘要引言正文内容什么是嵌套数据结构&#xff1f;例子&#xff1a; 遍历嵌套List和Map遍历嵌套List遍历嵌套Map 拆分嵌套数据结构拆分嵌套List拆分嵌套Map &#x1f914; Q…

【CTF Web】CTFShow web18 Writeup(文件包含漏洞+日志注入+RCE)

web18 1 阿呆加入了过滤&#xff0c;这下完美了。 解法 <?php if(isset($_GET[c])){$c$_GET[c];if(!preg_match("/php|file/i",$c)){include($c);}}else{highlight_file(__FILE__); } ?>用 dirsearch 扫了下&#xff0c;什么都没找到。 Wappalyzer 检测到 …

计算机视觉与模式识别实验1-3 图像滤波

文章目录 &#x1f9e1;&#x1f9e1;实验流程&#x1f9e1;&#x1f9e1;1. 对图像加入椒盐噪声&#xff0c;并用均值滤波进行过滤2.对图像加入高斯噪声&#xff0c;并用高斯滤波进行过滤3.对图像加入任意噪声&#xff0c;并用中值滤波进行过滤4.读入一张灰度图像&#xff0c;…

Java项目:95 springboot班级回忆录的设计与实现

作者主页&#xff1a;舒克日记 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 本管理系统有管理员和用户。 本海滨学院班级回忆录管理员功能有个人中心&#xff0c;用户信息管理&#xff0c;班委信息管理&#xff0c;班级信息管理…

云计算-高级云资源配置(Advanced Cloud Provisioning)

向Bucket添加公共访问&#xff08;Adding Public Access to Bucket&#xff09; 在模块5中&#xff0c;我们已经看到如何使用CloudFormation创建和更新一个Bucket。现在我们将进一步更新该Bucket&#xff0c;添加公共访问权限。我们在模块5中使用的模板&#xff08;third_templ…

多维数组找最大值

调用JavaScript的一个内置函数&#xff1a;Math.max() <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title…

汇编原理(二)寄存器——CPU工作原理

寄存器&#xff1a;所有寄存器都是16位&#xff08;0-15&#xff09;&#xff0c;可以存放两个字节 AX,BX,CX,DX存放一般性数据&#xff0c;称为通用寄存器 AX的逻辑结构。最大存放的数据为2的16次方减1。可分为AH和AL&#xff0c;兼容8位寄存器。 字&#xff1a;1word 2Byte…

c++实现:小型公司的信息管理系统(关于多态)

前言&#xff1a; 介绍员工信息&#xff1a;一个小型公司的人员信息管理系统 某小型公司&#xff0c;主要有四类人员&#xff1a;经理、技术人员、销售经理和推销员。现在&#xff0c;需要存储这些人员的姓名、编号、级别、当前薪水。计算月薪总额并显示全部信息人员编号基数为…

前端组件业务数据选择功能优雅写法

1. 业务场景 后台管理在实际业务中&#xff0c;经常可见的功能为&#xff1a;在当前的页面中从其他列表中选择数据。 例如&#xff0c;在一个商品活动列表页面中 需要选择配置的商品。 2. 遇到问题 从代码划分的角度来说&#xff0c;每个业务列表代码首先分散开来&#xff0…

基于Weaviate构建多模态检索和多模态检索增强(RAG): Building Multimodal Search and RAG

Building Multimodal Search and RAG 本文是学习 https://www.deeplearning.ai/short-courses/building-multimodal-search-and-rag/ 这门课的学习笔记。 What you’ll learn in this course Learn how to build multimodal search and RAG systems. RAG systems enhance an …

张大哥笔记:下一个风口是什么?

我们经常会问&#xff0c;下一个风口是什么&#xff1f;我们可以大胆预测一下&#xff0c;2024年的风口是什么呢&#xff1f; 40年前&#xff0c;如果你会开车&#xff0c;那就是响当当的铁饭碗&#xff1b; 30年前&#xff0c;如果你会英语和电脑&#xff0c;那也绝对是个人才…