【SSM框架系列】Spring IoC(控制反转) & DI(依赖注入)

2023-11-03

Spring是什么

  • Spring是分层的 Java SE/EE应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核。

  • 提供了展现层 SpringMVC和持久层 Spring JDBCTemplate以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE 企业应用开源框架

IoC(Inverse of Control)控制反转

  • 控制是什么?
    • 控制是bean对象
  • 反转是是什么?
    • 反转的是bean对象的获取方式以及对象之间的依赖关系,之前我们要什么对象,就new什么对象,我们自己new
    • 现在,我们要什么对象,管Spring去要,创建的过程交给Spring,我们把创建对象的权力做了反转
    • 原来都是我们自己new,现在有Spring去创建,Bean对象之间的依赖关系也做了反转

Spring的优势

1)方便解耦,简化开发
 通过 Spring 提供的 IoC容器,可以将对象间的依赖关系交由 Spring 进行控制,避免硬编码所造成的过度耦合。
 用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
2)AOP 编程的支持
 通过 Spring的 AOP 功能,方便进行面向切面编程,许多不容易用传统 OOP 实现的功能可以通过 AOP 轻松实现。

3)声明式事务的支持
 可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务管理,提高开发效率和质量。

4)方便程序的测试
 可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。
5)方便集成各种优秀框架
 Spring对各种优秀框架(Struts、Hibernate、Hessian、Quartz等)的支持。

6)降低 JavaEE API 的使用难度
 Spring对 JavaEE API(如 JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些 API 的使用难度大为降低。

7)Java 源码是经典学习范例
 Spring的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对Java 设计模式灵活运用以及对 Java技术的高深
 造诣。它的源代码无意是 Java 技术的最佳实践的范例。

Spring的体系结构

在这里插入图片描述

spring基本入门

  • 首先导入 Spring 开发的基本包坐标
			<dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.0.5.RELEASE</version>
            </dependency>
  • 编写 Dao 接口和实现类

  • 创建 Spring 核心配置文件
    在这里插入图片描述

  • 配置 Spring 配置文件(把我们的类交给Spring去创建,并且帮我们存进Spring的容器)

 <?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> 标签中的 id 属性是用来标记一个Bean对象,id值要唯一
		* class属性是Spring对象管理的全限定类名
		* scope属性是Spring管理这个对象是单例还是多例的,不写,默认单例
		*/
       <bean id="userDao" class="cs.wy.dao.impl.UserDaoImpl"></bean>
       // 等价于
       UserDao userDao = new UserDaoImpl()</beans>
  • scope:指对象的作用范围,取值如下:
取值范围 说明
singleton 默认值,单例的
prototype 多例的
request WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中
session WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中
global session WEB 项目中,应用在 Portlet 环境,如果没有 Portlet 环境那么globalSession 相当于 session
  • 使用 Spring 的 API 获得 Bean 实例
// 从Spring容器中获取它帮我们创建的对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");   				 
userDao.save();

Bean实例化三种方式

Bean标签:用于配置对象交由Spring 来创建。
默认情况下它调用的是类中的无参构造函数,如果没有无参构造函数则不能创建成功。

基本属性:
id:Bean实例在Spring容器中的唯一标识
class:Bean的全限定名称

  • 使用无参构造方法实例化
// 它会根据默认无参构造方法来创建类对象,如果bean中没有默认无参构造函数,将会创建失败

// Spring的Bean标签配置方式
<bean id="userDao" class="cs.wy.dao.impl.UserDaoImpl"/>
// java方式创建对象
UserDao userDao = new UserDaoImpl();
  • 工厂静态方法实例化
    public class StaticFactoryBean {
        public static UserDao createUserDao(){    
        return new UserDaoImpl();
        }
    }
// 使用某个类中的静态方法创建对象,存入Spring容器

// Spring配置方式
<bean id="userDao" class="cs.wy.factory.StaticFactoryBean" 
          factory-method="createUserDao" />
// java方式
UserDao userDao = StaticFactoryBean.createUserDao();

3) 工厂实例方法实例化

   public class DynamicFactoryBean {  
    	public UserDao createUserDao(){        
    		return new UserDaoImpl(); 
    	}
    }
// 使用工厂中的普通方法创建对象
// java方式
DynamicFactoryBean factoryBean = new DynamicFactoryBean();
UserDao userDao = factoryBean.createUserDao();

// Spring 配置方式
    <bean id="factoryBean" class="cs.wy.factory.DynamicFactoryBean"/>
    <bean id="userDao" factory-bean="factoryBean" factory-method="createUserDao"/>

Bean的依赖注入

  • 依赖注入(Dependency Injection):它是 Spring 框架核心 IOC 的具体实现。

  • 在编写程序时,通过控制反转,把对象的创建交给了 Spring,但是代码中不可能出现没有依赖的情况。

  • IOC 解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。

  • 那这种业务层和持久层的依赖关系,在使用 Spring 之后,就让 Spring 来维护了。

  • 简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取

Bean的依赖注入方式

  • 构造方法:
// 创建有参构造
public class UserServiceImpl implements UserService {
    @Override
    public void save() {
    ApplicationContext applicationContext = new 
                     ClassPathXmlApplicationContext("applicationContext.xml");       UserDao userDao = (UserDao) applicationContext.getBean("userDao");    
              userDao.save();
        }
     }
}

// 构造方法注入  配置Spring容器调用有参构造时进行注入
<bean id="userDao" class="cs.wy.dao.impl.UserDaoImpl"/>
<bean id="userService" class="cs.wy.service.impl.UserServiceImpl">
	<constructor-arg name="userDao" ref="userDao"/>
</bean>
  • set方法
	// 在UserServiceImpl中添加setUserDao方法
	public class UserServiceImpl implements UserService {
        private UserDao userDao;
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;  
        } 
	}

	// 配置Spring容器调用set方法进行注入
	<bean id="userDao" class="cs.wy.dao.impl.UserDaoImpl"/>
    <bean id="userService" class="cs.wy.service.impl.UserServiceImpl">
    	<property name="userDao" ref="userDao"/>
    </bean>
  • set方法:P命名空间注入
/*
*	P命名空间注入本质也是set方法注入,但比起上述的set方法注入更加方便,主要体现在配置文件中,如下:
*	首先,需要引入P命名空间:
*		xmlns:p="http://www.springframework.org/schema/p"
*	其次,需要修改注入方式
<bean id="userService" class="cs.wy.service.impl.UserServiceImpl" p:userDao-ref="userDao"/>

Bean的依赖注入的数据类型

上面的操作,都是注入的引用Bean,处了对象的引用可以注入,普通数据类型,集合等都可以在容器中进行注入。

注入数据的三种数据类型

  • 普通数据类型

  • 引用数据类型

  • 集合数据类型

其中引用数据类型,此处就不再赘述了,之前的操作都是对UserDao对象的引用进行注入的,下面将以set方法注入为例,演示普通数据类型和集合数据类型的注入。

Bean的依赖注入的数据类型

(1)普通数据类型的注入

    public class UserDaoImpl implements UserDao {
    	private String name;
        private int age;
        public void setName(String name) {
            this.name= name;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public void save() {
            System.out.println(name+"==="+age);
            System.out.println("UserDao save method running....");   
        }
    }
    

    <bean id="userDao" class="cs.wy.dao.impl.UserDaoImpl">
        <property name="name" value="赵丽颖"></property>
        <property name="age" value="18"></property>
    </bean>

(2)集合数据类型(List< String >)的注入

 	public class UserDaoImpl implements UserDao {
    	private List<String> strList;
    	public void setStrList(List<String> strList) {
    		this.strList = strList;
    	}
    	public void save() {
            System.out.println(strList);
            System.out.println("UserDao save method running....");
    	}
    }

    <bean id="userDao" class="cs.wy.dao.impl.UserDaoImpl">
        <property name="strList">
            <list>
                <value>aaa</value>
                <value>bbb</value>
                <value>ccc</value>
            </list>
        </property>
    </bean>

(3)集合数据类型(List< User >)的注入

  	public class UserDaoImpl implements UserDao {
    	private List<User> userList;
    	public void setUserList(List<User> userList) {
    		this.userList = userList;  
     	}
    	public void save() {
    		System.out.println(userList);
    		System.out.println("UserDao save method running....");
    	}
    }

    <bean id="u1" class="cs.wy.domain.User"/>
    <bean id="u2" class="cs.wy.domain.User"/>
    <bean id="userDao" class="cs.wy.dao.impl.UserDaoImpl">
        <property name="userList">
            <list>
                <bean class="cs.wy.domain.User"/>
                <bean class="cs.wy.domain.User"/>
                <ref bean="u1"/>
                <ref bean="u2"/>       
            </list>
        </property>
    </bean>

(4)集合数据类型( Map<String,User> )的注入

	public class UserDaoImpl implements UserDao {
        private Map<String,User> userMap;
        public void setUserMap(Map<String, User> userMap) {
        	this.userMap = userMap;
        }    
    	public void save() {      
    		System.out.println(userMap);
    		System.out.println("UserDao save method running....");
    	}
    }

    <bean id="u1" class="cs.wy.domain.User"/>
    <bean id="u2" class="cs.wy.domain.User"/>
    <bean id="userDao" class="cs.wy.dao.impl.UserDaoImpl">
        <property name="userMap">
            <map>            
                <entry key="user1" value-ref="u1"/>
                <entry key="user2" value-ref="u2"/>
            </map>
        </property>
    </bean>

(5)集合数据类型(Properties)的注入

 	public class UserDaoImpl implements UserDao {
        private Properties properties;
        public void setProperties(Properties properties) {
            this.properties = properties;
        }
    	public void save() {
    		System.out.println(properties);
    		System.out.println("UserDao save method running....");
    	}
    }

    <bean id="userDao" class="cs.wy.dao.impl.UserDaoImpl">
        <property name="properties">
            <props>
                <prop key="p1">aaa</prop>
                <prop key="p2">bbb</prop> 
                <prop key="p3">ccc</prop>
            </props>
        </property>
    </bean>

引入其他配置文件(分模块开发)

实际开发中,Spring的配置内容非常多,这就导致Spring配置很繁杂且体积很大,所以,可以将部分配置拆解到其他配置文件中,而在Spring主配置文件通过import标签进行加载

<import resource="applicationContext-xxx.xml"/>

spring相关API

  • ApplicationContext的继承体系

applicationContext:接口类型,代表应用上下文,可以通过其实例获得 Spring 容器中的 Bean 对象
在这里插入图片描述

  • ApplicationContext的实现类

    • ClassPathXmlApplicationContext :它是从类的根路径下加载配置文件 推荐使用这种

    • FileSystemXmlApplicationContext :它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。

    • AnnotationConfigApplicationContext: 当使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。

  • getBean()方法使用

	public Object getBean(String name) throws BeansException {  
    	assertBeanFactoryActive();   
    	return getBeanFactory().getBean(name);
    }
    public <T> T getBean(Class<T> requiredType) throws BeansException {
    	assertBeanFactoryActive();
    	return getBeanFactory().getBean(requiredType);
    }

其中,当参数的数据类型是字符串时,表示根据Bean的id从容器中获得Bean实例,返回是Object,需要强转。
当参数的数据类型是Class类型时,表示根据类型从容器中匹配Bean实例,当容器中相同类型的Bean有多个时,则此方法会报错

getBean()方法使用

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService1 = (UserService) applicationContext.getBean("userService");
UserService userService2 = applicationContext.getBean(UserService.class);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【SSM框架系列】Spring IoC(控制反转) & DI(依赖注入) 的相关文章

随机推荐

  • 几个效率高的排序算法

    实用排序算法 复杂度小于等于O n 2 中效率最低但实现并不是最简单的的两个 C C 教材却总喜欢拿来大讲特讲 非常不利于初学者养成 程序效率 的思维 实际上 各种排序算法里 除了堆排序实现较为复杂外 从代码量的角度 大多数算法都不比冒泡
  • matlab标准数据,Matlab数据标准化实现

    在多属性综合评价问题中 为了消除量纲差异带来指标不可公度性问题 往往需要对原始评价矩阵进行标准化处理 通过将不同量纲进行变换 变为无量纲的标准化指标 考虑到原始评价矩阵可能同时有多种类型的指标 比如 某个评价问题中可能同时有正向指标 越大越
  • 五分钟让你彻底了解TDD、ATDD、BDD&RBE

    在目前比较流行的敏捷开发模式 如极限编程 Scrum方法等 中 推崇 测试驱动开发 Test Driven Development TDD 测试在先 编码在后的开发实践 TDD有别于以往的 先编码 后测试 的开发过程 而是在编程之前 先写测
  • PostgreSQL用户登录失败自动锁定的解决办法

    墨墨导读 PostgreSQL使用session exec插件实现用户密码验证失败几次后自动锁定 本文介绍一种处理方案 一 插件session exec安装配置篇 下载插件并编译安装 https github com okbob sessi
  • RPA机器人的两种类型与未来发展

    眼下 RPA 机器人流程自动化 日渐成为业务流程优化重要解决方案和企业关注的重点 RPA不仅可以改善企业的工作方式 带来效率的提升和超高的投资回报率 ROI 其潜在的其他好处也是其他工具所无法比拟的 如改善客户体验 提高员工满意度 提高人才
  • 机器学习(一)svm运用实例

    机器学习 一 svm运用实例 这里我使用sklearn svm SVC函数 首先介绍一下函数参数 sklearn svm SVC C 1 0 kernel rbf degree 3 gamma auto coef0 0 0 shrinkin
  • TCPIP四层协议

    TCP IP四层协议 在说TCP IP四层协议之前 就不得不说OSI七层模型 OSI七层模型 自底向上依次是物理层 数据链路层 网络层 传输层 会话层 表示层 应用层 TCP IP体系结构的优点 1 简化了计算机网络的结构 从原来的七层模型
  • UITabBarItem

    UITabBarController UITabBar UIBarItem UITabBarItem UITabBarItem就是UITabBar上显示的小按钮 我们也可以定制系统UITabBarItem按钮 只需通过UITabBarIte
  • C/C++的64位整型 zz

    为了和DSP兼容 TSint64和TUint64设置成TSint40和TUint40一样的数 结果VC中还是认为是32位的 显然不合适 typedef signed long int TSint64 typedef unsigned lon
  • 初始化 Repo错误 错误信息:fatal: error [Errno 111] Connection refused

    错误信息 fatal error Errno 111 Connection refused 解决方法 修改home 目录下的 bashrc文件 gedit bashrc 在文件的末尾添加如下命令 export PATH bin PATH e
  • QT5.6静态编译添加ODBC数据库

    qt5 6已经编译好 现在添加ODBC数据库的支持 1 进入qt everywhere opensource src 5 6 3 qtbase src plugins sqldrivers odbc目录 运行qmake exe 然后再运行n
  • C语言学生管理系统课程设计

    include
  • cookie和session之间的关系

    当登录接口依赖token的 可以先登录后 token存到一个yaml或者json或者ini的配置文件里面 后面所有的请求去拿这个数据就可以全局使用 如果是cookies的参数 可以用session自动关联 详情如下 一 cookie与ses
  • 超全!深度学习在计算机视觉领域的应用一览

    计算机视觉领域正在从统计方法转向深度学习神经网络方法 计算机视觉中仍有许多具有挑战性的问题需要解决 然而 深度学习方法正在针对某些特定问题取得最新成果 在最基本的问题上 最有趣的不仅仅是深度学习模型的表现 事实上 单个模型可以从图像中学习意
  • MySQL查询数据库中所有表名及注释等信息

    1 查询所有表名 select table name from information schema tables where table schema 当前数据库 2 查看所有字段和字段注释 SELECT COLUMN NAME 字段 c
  • torch.Size理解

    torch Size括号中有几个数字就是几维 第一层 最外层 中括号里面包含了两个中括号 以逗号进行分割 这就是 2 3 4 中的2 第二层中括号里面包含了三个中括号 以逗号进行分割 这就是 2 3 4 中的3 第三层中括号里面包含了四个数
  • Python中MD5加密

    MD5是什么 下面的概念是百度百科的 Message Digest Algorithm MD5 中文名为消息摘要算法第五版 为计算机安全领域广泛使用的一种散列函数 用以提供消息的完整性保护 该算法的文件号为RFC 1321 R Rivest
  • ev3编程 python_乐高 EV3 高级编程 - 第四课:Python 模块

    译者按 使用 ev3dev Linux 系统并用 Python 编程的人数比例很低 好像这一课这样写 Python 编程的就更少了 你会发现程序的重用率会大大的提高 EV3 Lesson 4 Python Modules EV3 第 4 课
  • win10 电脑 .Net framework3.5 组件无法安装0x800f801f

    最近在win10上安装了MotorControl Workbench 5 4 0软件需要用到 Net framework3 5 但是安装Net framework3 5老是出错 无论是下载离线安装包安装 还是通过 控制面板 中 程序 的 启
  • 【SSM框架系列】Spring IoC(控制反转) & DI(依赖注入)

    Spring是什么 Spring是分层的 Java SE EE应用 full stack 轻量级开源框架 以 IoC Inverse Of Control 反转控制 和 AOP Aspect Oriented Programming 面向切