文章目录
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标签的常用属性
-
id:取得名称,可以任意命名
– id的属性值,不能包含一些特殊的符号,一般有一个或多个单词组成
– 根据ID得到配置的对象 -
class : 创建对象所属类的全路径
-
name : 跟id本身是一个样子的,区别就是Id不能包含特殊符号,但是name可以包含特殊符号,但是name现在已经不用了,之前Spring集成Struts1的时候,遗留的一个name属性,现在Struts1不用了,现在用id取代了。 -
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.属性注入
- 构造注入:通过带参构造可以给属性赋值
- 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.依赖注入和控制反转是对同一件事情的不同描述,从某个方面讲,就是它们描述的角度不同。
依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应用程序依赖容器创建并注入它所需要的外部资源;
而控制反转是从容器的角度在描述,描述完整点:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。