(二)Spring中的ioc
目录
Spring的ioc操作
- 把对象的创建交给Spring管理
- ioc操作分为两种
 - 配置文件方式
- 注解方式
 
ioc底层使用的技术
- xml配置文件
- dom4j解析- xml文件、
- 工厂设计模式
- 反射
ioc底层原理
需求:创建一个类,并其调用其非静态方法;、
- 没有使用Spring之前
我们知道不能在servlet中,直接new services层对象,导致 web 层和 services 层的耦合太高;没接触Spring之前,我们一般使用工厂来解耦web 层和 services 层 ;
但是这样做,又导致services 层和 工厂 紧紧的关联在一起,它们的耦合又变得太高了!比如,现在services层,有类的名字发生了改变,那么工厂类中,也需要相应的改变类的名字;因此本质上,并没有解决耦合的问题;
- 使用Spring之后
 
假如我们在,配置文件中,配置要创建对象的类,然后创建一个工厂类,在工厂类中,使用dom4j解析xml配置文件,然后利用反射,创建对象;
这样,后期即使要改动,比如改动了类的名字,我们也只需要在配置文件改动类的名字,其他地方的代码是不需要改变的;
Spring的ioc,就是这样帮我们创建对象的;上面也就是IOC的底层原理;
ioc入门案例
- 导入 - Spring jar包- 做 - spring最基本的功能时,只需要导入- 四个核心的- jar包:- Beans、- Core、- Context、- SpEL即可;
- 导入支持日志的 - jar包- 因为,Spring本身没有支持日志;
 - 日志 jar:- log4j、- commons-logging;
- spring配置文件- (1) 配置文件的名字和位置,不是固定的,可以随便放置;官方建议放在 - src目录下,取名为- ApplicationContext.xml;- (2) 引入 - schema约束文件- <?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 "
 default-autowire="byName"> <bean id="user" class="xin.ijava.domian.User"/>
 </beans>
 
- 代码实例 - @Test
 public void testIoc(){
 // 1、加载Spring配置文件,参数配置文件的路径+名字;从src开始写
 ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
 // 2、获取配置文件中配置的对象
 User user = (User) context.getBean("user");
 System.out.println(user);
 user.speak();
 } ------------------- 输出 ------------------------------- xin.ijava.domian.User@6c1ec7a3
 User 说话、、
bean管理(xml方式)
也就是 ioc 操作
- bean实例化(三种方式实现)- 实例化,就是通过配置文件由 Spring 来创建对象; 基本上只用第一种方式创建对象;
 - 第一种:使用类的- 无参构造器创建(重点)- 只需要写出一个 - bean类即可;- 配置文件中写法 - <!--无参构造器创建bean实例-->
 <bean id="user" class="xin.ijava.domian.User"/>
 
 - 第二种:使用- 静态工厂创建(没有创建工厂对象)- 除了 - bean类,还需要写一个- bean的工厂,工厂中含有静态方法,返回- bean;- 配置文件中写法: - class属性为:工厂类;- factory-method属性为:工厂静态方法- <!--静态工厂方法创建bean实例-->
 <bean id="bean2" class="xin.ijava.domian.Bean2Factory" factory-method="getBean2"/>
 
 - 第三种:使用- 实例工厂创建(创建工厂了对象)- 配置文件中写法:先创建工厂实例,再利用工厂实例创建 - bean实例- <!--实例工厂方法创建bean实例-->
 <bean id="bean3Factory" class="xin.ijava.domian.Bean3Factory"/>
 <bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"/>
- bean标签常用属性- id:- 起名字,名字可以为任意名字,但是名字中不可以有特殊字符; 可以根据 id,获取配置对象;
 - class:- 创建对象所在类的全路径;
 - name:- 功能和 id 一样,但是可以包含特殊字符,主要是为了整合 Struts1 的遗留问题 现在也不再使用,推荐使用 id ;
 - scope:- Bean 的作用范围 ;有几个可选值 ; singleton :默认值,单例
 prototype :多例 request:Spring创建的对象,保存在request域中 ;
 session:Spring创建的对象,保存在session域中 ;
 globalSession:应用在 Porlet 环境,如果没有 Porlet 环境,则globalSession相当于 session ; 最后的 globalSession ,用于单点登录的时候;
 
- 属性注入 - 属性注入:创建对象的时候,往类里面属性设置值; 属性注入有三种方式;
 - 第一种:使用- set方法注入(重点)- 使用这样方式,类中必须要有无参构造器,因为底层实现的时候,也是先创建对象,再赋值属性的; - 配置文件写法: - <!--set 方法注入,需要有无参的构造器存在,因为是先new对象出来,再复制的-->
 <bean id="book2" class="xin.ijava.domian.Book" >
 <property name="name" value="哆啦A梦"></property>
 </bean>
 
 - 第二种:使用- 有参构造器方法注入- 这样注入,不需要有无参构造器存在,因为底层实现的时候,是直接调用有参构造器; - 配置文件写法: - <!--属性注入。使用有参构造器-->
 <bean id="book1" class="xin.ijava.domian.Book" >
 <constructor-arg name="name" value="肥嘟嘟左卫门"></constructor-arg>
 </bean>
- 注入 - 对象类型属性- 使用场景:在 Services 层调用 Dao 层方法,我们将dao的创建工作交给 Spring
 - /**
 * Dao层代码
 */
 package xin.ijava.domian; public class UserDao {
 public void add(){
 System.out.println("UserDao ... add");
 }
 } ------------------------------------------- package xin.ijava.domian;
 /**
 * Service层代码
 */
 public class Service {
 // 将dao层作为属性
 private UserDao userDao ; public UserDao getUserDao() {
 return userDao;
 }
 // 设置set 方法,便于 set 注入
 public void setUserDao(UserDao userDao) {
 this.userDao = userDao;
 } public void add(){
 System.out.println("Service ... add");
 userDao.add();
 } }- 配置文件写法: - <!--对象属性注入-->
 <!--创建dao层对象-->
 <bean id="userDao" class="xin.ijava.domian.UserDao"></bean>
 <!--创建services层对象,将dao层对象注入进去-->
 <bean class="xin.ijava.domian.Service" id="service">
 <!--对于引用类型,使用 ref ,不可使用value-->
 <property name="userDao" ref="userDao"></property>
 </bean>
 
- P名称空间注入- <beans xmlns="http://www.springframework.org/schema/beans"
 <!--自定义名称空间P-->
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <!--P名称空间注入-->
 <bean id="book3" class="xin.ijava.domian.Book" p:name="啦啦啦"/>
- 复杂类型属性注入- 涉及 - 数组、- map、- list、- properties等类型 ;- <!--复杂类型属性注入-->
 <bean class="xin.ijava.domian.Bean4" id="bean4"> <!--为数组赋值。使用list,就是list一脉下面的集合,就是有list赋值-->
 <!--list下面使用value-->
 <property name="strings">
 <list>
 <value>那么多唱歌动听的人呦。。。</value>
 <value>千秋直美</value>
 <value>村下孝藏</value>
 <value>那么多唱歌动听的人呦。。。</value>
 </list>
 </property> <!--为list集合赋值-->
 <property name="list">
 <list>
 <value>哈哈</value>
 <value>呵呵</value>
 </list> </property> <!--为map赋值-->
 <!--使用键值对一脉的,都是用map赋值-->
 <!--而map使用 entry-->
 <property name="map">
 <map>
 <entry key="driverClass" value="com.mysql.jdbc.driver"></entry>
 </map>
 </property> <!--为properties赋值-->
 <!--使用props赋值-->
 <property name="properties">
 <props>
 <prop key="name" >root</prop>
 <prop key="password" >root</prop>
 </props>
 </property>
 </bean>
IOC和DI的区别
IOC:控制反转,是将对象的创建交给 Spring 来完成 ; 
DI :依赖注入,是为对象的属性赋值 ;
关系:DI 不能单独存在,必须依赖于 IOC;
Spring整合WEB的原理
- 加载 - Spring的核心配置文件- // 1、加载Spring配置文件,参数配置文件的路径+名字;从src开始写
 ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
 
- new对象的效率问题- 假如每个地方需要用到配置文件的话,都new 一个对象的话,那么效率会低到爆炸; - 你可能会想到在 - 静态代码块里面- new,然后复用它,这样第一次使用的时候,还是需要等待的;
- 在服务器启动的时候,创建 - 配置文件对象- 将压力扔给服务器,在服务器启动的时候,让服务器创建 - 配置文件对象,这样第一次用的时候,对象就已经被创建好了;
- 共享 - 配置文件对象- 服务器在启动的时候,会为每一个项目,创建一个 - servletContext对象,使用监听器,监听- servletContext对象的创建 ,就监听到服务器的启动,在监听器里面创建- 配置文件对象,然后将其添加进- servletContext域中,就可以共享- 配置文件对象了 ;- 上面说的,也就是 - Spring自动创建- 配置对象的原理
Spring 整合的具体操作
- Spring中具体操作步骤- 上面说到,我们可以通过 - 监听器、- servletContext实现在服务器启动的时候,加载配置文件,创建配置文件对象 ;- 但是在 - Spring中,不需要我们自己动手写上面的代码。- Spring对其做了封装 ;- Spring自己封装了一个- 监听器,我们那只需要去配置这个- 监听器即可,配置之前,确保导入了- Spring-web的包 ;- <!--配置Spring的监听器-->
 <listener>
 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>- 加上监听器以后,这时候会报错: - Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]- 告诉我们,在 - WEB-INF目录下,找不到名字叫- applicationContext.xml的配置文件 ;- 这时候,我们可以将配置文件放在对应的目录下面,起对应的名字 ; - 但是,我们刚学 - Spring的时候,就被告知配置文件是可以随便放在哪里的,名字随便起的 ;这时候,需要我们在 Web.xml 中再配置一下:
 <!--配置Spring的配置文件路径-->
 <context-param>
 <param-name>contextConfigLocation</param-name>
 <param-value>classpath:ApplicationContext.xml</param-value>
 </context-param>- 其中: - <param-name>属性的值是固定的 ;- <param-value>属性的值是- classpath:后面跟上- Spring配置文件的位置和名字 ;- 然后运行项目,在控制台可以看到: - INFO XmlBeanDefinitionReader:317 - Loading XML bean definitions from class path resource [ApplicationContext.xml]- 可以看到,我们的 - Spring配置文件被加载了 ;
(二)Spring中的ioc的更多相关文章
- Spring中的IOC
		在学习spring的时候,最常听到的词应该就是IOC和AOP了,以下,我从我的角度再次理解一下Spring里的IOC和AOP. IOC简单介绍 IoC(InversionofControl):IoC就 ... 
- 用IDEA详解Spring中的IoC和DI(挺透彻的,点进来看看吧)
		用IDEA详解Spring中的IoC和DI 一.Spring IoC的基本概念 控制反转(IoC)是一个比较抽象的概念,它主要用来消减计算机程序的耦合问题,是Spring框架的核心.依赖注入(DI)是 ... 
- 理解Spring中的IoC和DI
		什么是IoC和DI IoC(Inversion of Control 控制反转):是一种面向对象编程中的一种设计原则,用来减低计算机代码之间的耦合度.其基本思想是:借助于"第三方" ... 
- Spring中的IOC示例
		Spring中的IOC示例 工程的大概内容是: 一个人在中国时用中国话问候大家,在国外时用英语问候大家. 其中, IHelloMessage是接口,用来定义输出问候信息 public interfac ... 
- 详谈 Spring 中的 IOC 和 AOP
		这篇文章主要讲 Spring 中的几个点,Spring 中的 IOC,AOP,下一篇说说 Spring 中的事务操作,注解和 XML 配置. Spring 简介 Spring 是一个开源的轻量级的企业 ... 
- 分布式数据存储 之 Redis(二) —— spring中的缓存抽象
		分布式数据存储 之 Redis(二) -- spring中的缓存抽象 一.spring boot 中的 StringRedisTemplate 1.StringRedisTemplate Demo 第 ... 
- 理解Spring中的IOC和AOP
		我们是在使用Spring框架的过程中,其实就是为了使用IOC,依赖注入和AOP,面向切面编程,这两个是Spring的灵魂. 主要用到的设计模式有工厂模式和代理模式 IOC就是典型的工厂模式,通过ses ... 
- 浅谈Spring中的IOC容器
		一.IOC.DI基本概念 IoC(Inversion of Control)控制反转指的是把对象的创建,初始化,销毁等工作交给容器来做.由容器控制对象的生命周期(传统方式中是由我们程序员主动创建对象. ... 
- Spring中的IoC(控制反转)具体是什么东西
		IOC:inverse of Control: 控制反转. 意思是程序中的之间的关系,不用代码控制,而完全是由容器来控制.在运行阶段,容器会根据配置信息直接把他们的关系注入到组件中.同样,这也是 依赖 ... 
随机推荐
- npm传参技巧
			博主今天遇到一个问题,使用vue-cli-serve,想要用shelljs来执行vue-cli-serve,动态给它传“--port xxxx"但是发现”--port“怎么传都穿不进去,后面 ... 
- AGC023C Painting Machines
			题意 有一排\(n\)个格子,\(i\)操作会使\(i\)和\(i+1\)都变黑. 一个操作序列的得分为染黑所有格子时所用的步数 问所有排列的得分和. \(n\le 10^6\) 传送门 思路 有一个 ... 
- Java中RuntimeException和Exception
			在java的异常类体系中,Error和RuntimeException是非检查型异常,其他的都是检查型异常. 所有方法都可以在不声明throws的情况下抛出RuntimeException及其子类 不 ... 
- Mysql 原理以及常见mysql 索引等
			## 主键 超键 候选键 外键 (mysql数据库常见面试题) 数据库之互联网常用架构方案 数据库之互联网常用分库分表方案 分布式事务一致性解决方案 MySQL Explain详解 ## 数据库事务的 ... 
- 一个 TCP 连接可以发多少个 HTTP 请求
			第一个问题 第二个问题 第三个问题 第四个问题 第五个问题 曾经有这么一道面试题:从 URL 在浏览器被被输入到页面展现的过程中发生了什么? 相信大多数准备过的同学都能回答出来,但是如果继续问:收到的 ... 
- [Phoenix] Mix 命令
			mix phx.gen.html 命令生成模板: # 其中 name 和 age 是 schema 字段名称,后面跟的是类型 # 下面这样的写法,会生成 controller 和 service 层的 ... 
- Oracle中shrink space命令
			shrink_clause: http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_3001.htm#i2192484 ... 
- 解决jenkins日志爆满 DNS查询错误
			一.故障 公司的jenkins因为日志量太大把磁盘占满,进而影响了其他程序,仔细一看日志文件"/var/log/jenkins/jenkins.log"几分钟产生了30G的日志 日 ... 
- LayerDrawable
			层图形对象,包含一个Drawable数组,然后按照数组对应的顺序来绘制他们,索引 值最大的Drawable会被绘制在最上层!虽然这些Drawable会有交叉或者重叠的区域,但 他们位于不同的层,所以并 ... 
- Qt打开文件QFileDialog
			//打开Pts文件按钮点击事件void AnalysisPtsDataTool201905::OnOpenFileButtonClick(){ qDebug()<<"open f ... 
