【02】Spring IOC

1. IOC底层实现原理

  • IOC: Inversion of Control 控制反转. 指的是 对象的创建权反转(交给)给 Spring.
    作用是实现了程序的解耦合。
  • IOC的底层的原理所用的一些技术
    1). xml配置文件
    2).dom4j解析XML
    3).工厂设计模式
    4).反射

在这里插入图片描述
在这里插入图片描述

2. IOC基本的入门案例

2.1 导入jar包

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<spring.version>5.1.5.RELEASE</spring.version>
		<!-- Test -->
		<junit.version>4.11</junit.version>
	</properties>

	<dependencies>
		<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
		<dependency>
			<groupId>com.mchange</groupId>
			<artifactId>c3p0</artifactId>
			<version>0.9.5.2</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>4.0.0-b01</version>
			<scope>provided</scope>
		</dependency>
		<!-- https://mvnrepository.com/artifact/log4j/log4j -->
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/taglibs/standard -->
		<dependency>
			<groupId>taglibs</groupId>
			<artifactId>standard</artifactId>
			<version>1.1.2</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/junit/junit -->
		<!-- https://mvnrepository.com/artifact/junit/junit -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
		<!-- context、aop、beans、core、expression、jcl -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>${spring.version}</version>
		</dependency>
	</dependencies>

2.2 创建类,在类里面创建方法

	package com.hxzy.bean;
	
	public class Bean01 {
	
		public void testBean01() {
			System.out.println("Hello Spring !");
		}
	}

2.3 创建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"
		xmlns:context="http://www.springframework.org/schema/context"
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
		
		<bean id="bean01" class="com.hxzy.bean.Bean01"></bean>
	</beans>

2.4 代码编写测试创建对象

	public class Test {
		@org.junit.Test
		public void test1() {
			ApplicationContext context=new ClassPathXmlApplicationContext("spring/application-config.xml");
			Bean01 bean01 = (Bean01) context.getBean("bean01");
			bean01.testBean01();
		}
	}

3. Bean实例化的方式

3.1 使用类里面的无参构造(重点掌握)

	<bean id="bean01" class="com.hxzy.bean.Bean01"></bean>
  • 这种配置方式采用的是无参的构造,我们可以在无参构造里面打印一句话来证实
    当你的类里面没有无参的构造,会出现如下异常

在这里插入图片描述

3.2 使用静态工厂来创建(很少用)

    public class User2 {
        public void add() {
            System.out.println("add2()---------");
        }
    }

静态工厂,如下:

    public class User2Factory {
        public static User2 getInstance() {
            return new User2();
        }
    }

该工厂中有一个静态方法,该静态方法返回一个User2的实例,在Spring的配置文件中,我们看看如何生成User2的实例:

    <bean id="user2" class="org.sang.User2Factory" factory-method="getInstance"/>

还是bean节点,只是多了一个factory-method属性,该属性指明该类中的静态工厂方法名为getInstance,这样Spring框架就知道调用哪个方法来获取User2的实例了,测试代码如下:

    @Test
    public void test2() {
         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
         User2 user = (User2) context.getBean("user2");
         user.add();
    }

3.3 使用实例工厂来创建

实例工厂,顾名思义,就是我们工厂中的方法不是静态的。
实体类User3:

    public class User3 {
        public void add() {
            System.out.println("add3()---------");
        }
    }

工厂方法:

    public class User3Factory {
        public User3 getUser3() {
            return new User3();
        }
    }

在User3Factory类中有一个getUser3的方法,该方法返回一个User3类的实例,但是该方法不是静态的,那么我们在Spring的配置文件中要进行怎样的配置才能获取User3的一个实例呢?如下:

    <bean class="org.sang.User3Factory" id="user3Factory"/>
    <bean id="user3" factory-bean="user3Factory" factory-method="getUser3"/>

第一个bean用来获取user3Factory的实例,第二个bean则根据User3Factory的实例,然后指定factory-method,通过getUser3方法来获取User3的实例。
测试代码如下:

     @Test
     public void test3() {
         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
         User3 user = (User3) context.getBean("user3");
         user.add();
     }

4. Bean标签的常用属性

  1. id:取得名称,可以任意命名
    – id的属性值,不能包含一些特殊的符号,一般有一个或多个单词组成
    – 根据ID得到配置的对象

  2. class : 创建对象所属类的全路径

  3. name : 跟id本身是一个样子的,区别就是Id不能包含特殊符号,但是name可以包含特殊符号,但是name现在已经不用了,之前Spring集成Struts1的时候,遗留的一个name属性,现在Struts1不用了,现在用id取代了。

  4. scope : 主要掌握前面两个,后面三个了解一下。
    – 1.singleton:默认值,单例的。
    在这里插入图片描述
    – 2.prototype:多例的,多实例用在Struts的action,他用的就是多实例的,这就是他应用的场景。
    在这里插入图片描述
    – 3.request:WEB项目中,Spring创建Bean对象,将Bean的对象引入到request作用域中
    – 4.session:WEB项目中,Spring创建Bean对象,将Bean的对象引入到session作用域中
    – 5.global session:WEB项目中,应用在Portal环境,如果没有Portal环境那么,global session相当于session。(单点登录,例如,百度首页你登录以后,你到知道里面,到贴吧里面,到文库里,都是已经登录的状态,这就是global session,这个技术叫…单点登录)

5.属性注入

  1. 构造注入:通过带参构造可以给属性赋值
  2. set方法注入:通过setXXX()方法也可以给属性赋值

5.1 构造注入

  • 带参构造函数
    在这里插入图片描述

5.2 set方法注入

  • 无参构造,set方法
    在这里插入图片描述

6. P名称空间的注入

  • 无参构造,set方法
  • 添加 P 名称空间
    在这里插入图片描述
    在这里插入图片描述
  • 注入bean
    在这里插入图片描述

7. 注入复杂类型的属性

7.1 特殊符号

	<!-- <![CDATA[]]> 标记XML特殊字符 -->
	<property name="beanName">
		<value><![CDATA[<</>>]]></value>
	</property>

7.2 定义的内部的Bean

	<!-- 内部bean -->
	<property name="stu">
		<bean class="com.hxzy.bean.Student" p:stuId="33" p:stuName="小明"/>
	</property>

7.3 数组

	<!-- 数组 -->
	<property name="array">
		<list>
			<value>Java</value>
			<value>SQL</value>
			<value>JSP</value>
			<value>JSP</value>
		</list>
	</property>

7.4 List集合

	<!-- list 集合 -->
	<property name="list">
		<list>
			<value>Java</value>
			<value>SQL</value>
			<value>JSP</value>
			<value>JSP</value>
		</list>
	</property>

7.5 Set集合

	<!-- set 集合 -->
	<property name="set">
		<set>
			<value>Java</value>
			<value>SQL</value>
			<value>JSP</value>
			<value>JSP</value>
		</set>
	</property>

7.6 Map集合

	<!-- map 集合 -->
	<property name="map">
		<map>
			<entry>
				<key>
					<value>CN</value>
				</key>
				<value>China</value>
			</entry>
			<entry>
				<key>
					<value>USA</value>
				</key>
				<value>American</value>
			</entry>
		</map>
	</property>

7.7 Properties类型

	<!-- properties 属性文件 -->
	<property name="properties">
		<props>
			<prop key="driver">com.mysql.jdbc.Driver</prop>
			<prop key="url">jdbc:mysql://127.0.0.1:1433:XXX</prop>
			<prop key="uname">root</prop>
			<prop key="pwd">root</prop>
		</props>
	</property>

7.8 空字符串类型

	<!-- 空字符串 -->
	<property name="emptyValue">
		<value></value>
	</property>

7.9 null 值

	<!-- null -->
	<property name="nullValue">
		<null/>
	</property>

8. IOC和DI的区别

8.0 概述

  • 依赖注入(DI)和控制反转(IOC)是从不同的角度的描述的同一件事情,就是指通过引入IOC容器,利用依赖关系注入的方式,实现对象之间的解耦。
  • IOC 控制反转,指将对象的创建权,反转到Spring容器 ;
  • DI 依赖注入,指Spring创建对象的过程中,将对象依赖属性通过配置进行注入 ;
  • 依赖注入不能单独存在,它建立在IOC的基础之上。

8.1 IOC介绍

1.IOC是控制反转,把对象创建交给Spring管理

2.传统资源查找方式:要求组件向容器发起请求,查找资源作为回应,容器适时返回资源。

3.IOC查找方式:容器会主动将资源提供给它所管理的组件,组件只需要选择一个合适的方式来接收资源,也被称为查找的被动式。

4.创建对象实例的控制权从代码控制剥离到IOC容器控制(之前的写法,由程序代码直接操控使用new关键字),实际就是你在xml文件控制,控制权的转移是所谓反转,侧重于原理。

8.2 DI介绍

1.DI是依赖注入,向类里面的属性中,设置它的值

2.IOC的另一种表达方式:组件以一些预先定义好的方式(如:setter方法)接收来自容器的资源注入。

3.相对于IOC而言,这种表述更加直接。

4.创建对象实例时,为这个对象注入属性值或其它对象实例,侧重于实现。

8.3 关系

依赖注入不能单独存在,它建立在IOC的基础之上。

8.4 区别

1.它们是spring核心思想的不同方面的描述。

2.依赖注入和控制反转是对同一件事情的不同描述,从某个方面讲,就是它们描述的角度不同。

依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应用程序依赖容器创建并注入它所需要的外部资源

而控制反转是从容器的角度在描述,描述完整点:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源

猜你喜欢

转载自blog.csdn.net/Spectre_win/article/details/89454496
今日推荐