[Spring]IOC控制反转和DI依赖注入
从之前算起到现在接触Spring也已经有几天了,进度也不是很快,就只弄懂了控制反转和依赖注入那么一点东西.然后敲了两个demo
主要是因为之前没有学过,然后网上资源很多但是都不是面向我们初学者的,大多都是直接上一堆配置,一堆代码纯粹告诉我如何用,而我敲完之后却不知道原理,在这里我算是淌过几次坑了
我找过W3School,上面的基础挺详细,各种概念给你讲清楚,但是它的教程有点老,Spring教程好像最后更新是16年,而且,有些地方对小白不是很友好,比如他没有提供需要导入的jar包,这一点上How2j做的不错
但是个人感觉How2j上的是简洁版的Spring,站长省略掉了其中的一些东西,之后我干脆找了外面java培训的视频看,感觉挺不错,某宝上有教程卖,十多块就可以买到(这里真的不是打广告)
Spring框架的介绍就不多说了,
Spring的下载地址:http://repo.spring.io/release/org/springframework/spring/
Spring的依赖包下载:http://s3.amazonaws.com/dist.springframework.org/release/SPR/spring-framework-3.0.2.RELEASE-dependencies.zip(自从有些版本以后Spring就没有提供这个了)
IOC:
IOC称为控制反转,控制反转的意思就是将创建对象的权利转交,我们以前创建对象的方式是new Object();而这样容易造成对象之间高耦合,那么什么是耦合呢,我的理解是他们之间的关系过于紧密
这样如果我们需要加入新的功能的时候就要改动源代码,不仅不利于测试而且也会让程序不便扩展,那么在Spring采用什么方式生成对象,这里就要涉及到DI,即依赖注入了
那么问题来了
依赖是谁依赖谁,当然是程序依赖于IOC容器(ApplicationContext或者BeanFactory)
为什么要依赖,因为程序不再通过new Object()生成对象,必须通过容器所提供的资源来创建对象
注入的是什么,是容器中的资源(包括对象,常量等)
那么IOC这种方式是怎样来生成对象的呢
首先,在程序中,有一个applicationContext.xml的文件,当然其他名字也没问题,我们得到对象的方式就是通过解析这个XMl文件,然后再反射来得到对象的
首先看一个applicationContext.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-3.0.xsd"> <bean id="UserServiceImpl"
class="com.example.demo1.Implements.UserServiceImpl"
init-method="init"
destroy-method="destroy"
scope="prototype">
<constructor-arg name="service" ref="service"></constructor-arg>
</bean>
<bean id="service" class="com.example.demo1.Implements.UserServiceImpl"></bean>
</beans>
这里的bean标签通俗的来说,如果把ApplicationContext比作一个工厂的话,bean就是这个工厂的产品,然后工厂根据他里面的id和class(即要生成的对象对应的实现类)来生成对象
解析xml文件,得到他的class的名字,通过反射找到该类,再生成对象,通过这个过程,我们把对象的控制权完全交给了spring,而不是之前的new Object()
通过解析XML得到对象的代码:
ApplicationContext instance = new ClassPathXmlApplicationContext("applicationContext.xml");
UserServiceImpl serviceImpl = (UserServiceImpl) instance.getBean("UserServiceImpl");
serviceImpl.save();//save为对象的一个方法
ClassPathXmlApplicationContext表示是在工程路径下面搜索该XML文件,如果要在电脑磁盘中寻找.需要用FileSystemApplicationContext
bean标签的相关属性
拿上面的XML为例子
id表示对象的唯一标识,也就是说这个不同的bean的id是不同的,他的命名规范和java变量的命名规范是一样的,不能出现特殊字符,比如?><这些,同时也不能纯数字
name的话,可以用特殊字符和纯数字但是不能出现空格,但是就不同的bean可以用同一个,就像人的身份证和名字一样,身份证只有一个,但名字可以是相同的,但是这仅建立在指定ID的的情况下
如果没有指定ID,name会被当做id,同样还是会报错
对比这两张截图
init-method属性是bean的初始方法,在创建好bean后调用该方法。
destory-method属性是bean的销毁方法,在销毁bean之前调用该方法,一般在该方法中释放资源
scope属性表示bean的作用范围,scope有4个值:
singleton:表示整个IOC容器共享一个Bean,也就是说每次说每次通过getBean获取的bean都是同一个。
prototype:每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会创建一个新的bean实例。
request:每次HTTP请求将会生成各自的bean实例
session:每次会话请求对应一个bean实例
后面两个一般用于web项目中
autowire表示bean的自动装配,autowire的值有:
no : 默认值,不进行自动装配
byName : 根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配
byType : 如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配;如果存在多个该类型bean,那么抛出异常,并指出不能使用byType方式进行自动装配;如果没有找到相匹配的bean,则什么事都不发生,也可以通过设置dependency-check="objects" 让Spring抛出异常。
constructor:与byType方式类似,不同之处在于它应用于构造器参数。如果容器中没有找到与构造器参数类型一致的bean, 那么抛出异常
autodetect : 通过bean类的内省机制(introspection)来决定是使用constructor还是byType方式进行自动装配。如果发现默认的构造器,那么将使用byType方式,否则采用 constructor。
default:由上级标签的default-autowire属性确定。
注入
1.setter的方法
2.构造的方法
测试类
package com.example.demo1.Implements; import com.example.demo1.Interface.UserService; public class UserServiceImpl implements UserService {
private UserServiceImpl service;
public void init(){
System.out.println("初始化");
}
public void destroy(){
System.out.println("销毁");
}
public UserServiceImpl(UserServiceImpl service){
this.service = service;
} public void setService(UserServiceImpl service) {
this.service = service;
} public UserServiceImpl(){ }
@Override
public void save() {
System.out.println("保存信息"+this.hashCode());
}
}
<property name="service" ref="test"></property>对应setService()
<constructor-arg name="service" ref="service"></constructor-arg>对应构造函数 P名称空间注入
先在xml文件里添加一行
xmlns:p="http://www.springframework.org/schema/p"
对于非对象属性,直接采用P:属性名.即可以注入,例如我一个类中有name和password属性
那么在xml文件里便可以通过如下方式注入
<bean id="Client"
class="com.example.demo1.Implements.UserClientImpl"
p:name="lidong" p:password="123">
</bean>
SpEL表达式注入
SpEL全称SpringExpressionLanguage,SpEL 使用 #{...} 作为定界符 , 所有在大括号中的字符都将被认为是 SpEL , SpEL 为 bean 的属性进行动态赋值提供了便利。
通过 SpEL 可以实现:
- 通过 bean 的 id 对 bean 进行引用。
- 调用方式以及引用对象中的属性。
- 计算表达式的值
- 正则表达式的匹配。
看代码吧还是
<bean id="UserClient" class="com.example.demo1.Implements.UserClientImpl">
<property name="name" value="#{555*123}"></property>
<property name="password" value="#{123}"></property>
</bean>
这里我在name标签处使用了一个乘法
然后打印出,可以看出这里面进行了运算
[Spring]IOC控制反转和DI依赖注入的更多相关文章
- 学习Spring IOC控制反转和DI依赖注入总结
30岁的小曹,20岁的身体,还在坚持在能力允许控制范围内22点睡觉,5点起床锻炼身体,好好学习,除了加班或者像今天这样的深夜,再一次写已经有X百万人写过的 spring Ioc 的总结博客. 一.IO ...
- Spring的三大核心思想:IOC(控制反转),DI(依赖注入),AOP(面向切面编程)
Spring核心思想,IoC与DI详解(如果还不明白,放弃java吧) 1.IoC是什么? IoC(Inversion of Control)控制反转,IoC是一种新的Java编程模式,目前很多 ...
- [转帖]什么是IOC(控制反转)、DI(依赖注入)
什么是IOC(控制反转).DI(依赖注入) 2018-08-22 21:29:13 Ming339456 阅读数 20642 原文地址(摘要了部分内容):https://blog.csdn.net ...
- 谈谈php里的IOC控制反转,DI依赖注入
理论 发现问题 在深入细节之前,需要确保我们理解"IOC控制反转"和"DI依赖注入"是什么,能够解决什么问题,这些在维基百科中有非常清晰的说明. 控制反转(In ...
- IoC控制反转与DI依赖注入
IoC控制反转与DI依赖注入 IoC: Inversion of Control IoC是一种模式.目的是达到程序的复用.下面的两篇论文是对IoC的权威解释: InversionOfControl h ...
- 谈谈php里的IOC控制反转,DI依赖注入(转)
转自:http://www.cnblogs.com/qq120848369/p/6129483.html 发现问题 在深入细节之前,需要确保我们理解"IOC控制反转"和" ...
- Spring-初识Spring框架-IOC控制反转(DI依赖注入)
---恢复内容开始--- IOC :控制反转 (DI:依赖注入)使用ioc模式开发 实体类必须有无参构造方法1.搭建Spring环境下载jarhttp://maven.springframework. ...
- 三大框架 之 Spring(IOC控制反转、DI依赖注入)
目录 常用词汇 left join与left outer join的区别 Struts2的标签库导入 Spring Spring概述 什么是Spring spring特点 下载 IOC 什么IOC 传 ...
- spring(一) IOC 控制反转 、DI 依赖注入
IOC 控制反转:创建对象的方式 变成了由Spring来主导 IOC底层原理:对象工厂 1.导入jar包:4个核心jar和1个依赖jar spring-beans-4.3.9.RELEASE.jar ...
随机推荐
- 使用express框架和mongoose在MongoDB删除数据
使用remove()删除数据 remove({},function(err,doc){}) // 删除所有数据 remove({age:18},function(err,doc){}); //删除指 ...
- lambda表达式(c++11)
1.概念 1)lambda表达式是一个可调用的代码单元,它由一个捕获列表.一个参数列表.一个箭头.一个返回类型.一个函数体组成: 2)可以忽略参数列表和返回类型,但必须包含捕获列表和函数体: 3)忽略 ...
- C语言程序设计50例(三)(经典收藏)
[程序31]题目:请输入星期几的第一个字母来判断一下是星期几,如果第一个字母一样,则继续 判断第二个字母.1.程序分析:用情况语句比较好,如果第一个字母一样,则判断用情况语句或if语句判断第二个字母. ...
- IntelliJ IDEA 2017版 spring-boot 2.0.3 邮件发送搭建,概念梳理 (二)
第二部分 邮件发送历史 一.第一封邮件 1.1969年10月,世界上的第一封电子邮件 1969年10月世界上的第一封电子邮件是由计算机科学家Leonard K.教授发给他的同事的一条简短 ...
- UVa 11762 Race to 1 (数学期望 + 记忆化搜索)
题意:给定一个整数 n ,然后你要把它变成 1,变换操作就是随机从小于等于 n 的素数中选一个p,如果这个数是 n 的约数,那么就可以变成 n/p,否则还是本身,问你把它变成 1 的数学期望是多少. ...
- mysql delete from table 失败
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'; TRUNCATE TABLE ...
- 20155326 第十周课下作业-IPC
20155326 第十周课下作业-IPC 学习题目: 研究Linux下IPC机制:原理,优缺点,每种机制至少给一个示例,提交研究博客的链接 共享内存 管道 FIFO 信号 消息队列 学习过程 -IPC ...
- JavaScript 获取鼠标点击位置坐标
在一些DOM操作中我们经常会跟元素的位置打交道,鼠标交互式一个经常用到的方面,令人失望的是不同的浏览器下会有不同的结果甚至是有的浏览器下没结果,这篇文章就上鼠标点击位置坐标获取做一些简单的总结,没特殊 ...
- [LintCode] Longest Increasing Continuous subsequence
http://www.lintcode.com/en/problem/longest-increasing-continuous-subsequence/# Give you an integer a ...
- Visual Studio Code 显示隐藏的.git文件和目录
在默认设置中,Visual Studio Code 将下列文件文件排除在显示列表中: "files.exclude": { "**/.git": true, & ...