第
2
章
IoC 控制反转(这下边比较官方,我直接理解就是不用自己创建对象了或者说是通过另一种方式创建了对象。在ApplicationContext ac = new ClassPathXMLApplicationContext();中,spring初学者比较常用,对象放在了这个容器里。)
控制反转(
IoC
,
Inversion of Control
),是一个概念,是一种思想。指将传统上由程序代
码直接操控的对象调用权交给容器,通过容器来实现对象的装配和管理。控制反转就是对对
象控制权的转移,从程序代码本身反转到了外部容器。通过容器实现对象的创建,属性赋值,
依赖的管理。
IoC
是一个概念,是一种思想,其实现方式多种多样。当前比较流行的实现方式是依赖
注入。应用广泛。
依赖:
classA
类中含有
classB
的实例,在
classA
中调用
classB
的方法完成功能,即
classA
对
classB
有依赖。
Ioc
的实现:
依赖注入:
DI(Dependency Injection)
,程序代码不做定位查询,这些工作由容器自行
完成。
依赖注入
DI
是指程序运行过程中,若需要调用另一个对象协助时,无须在代码中创建
被调用者,而是依赖于外部容器,由外部容器创建后传递给程序。
Spring
的依赖注入对调用者与被调用者几乎没有任何要求,完全支持对象之间依赖关系
的管理。
Spring
框架使用依赖注入(
DI
)实现
IoC
。
Spring
容器是一个超级大工厂,负责创建、管理所有的
Java
对象,这些
Java
对象被称
为
Bean
。
Spring
容器管理着容器中
Bean
之间的依赖关系,
Spring
使用“依赖注入”的方式
来管理
Bean
之间的依赖关系。使用
IoC
实现对象之间的解耦和。
2.1
开发工具准备
开发工具:
idea2017
以上
依赖管理:
maven3
以上
jdk:1.8
以上
2.2 Spring
的第一个程序
springch01
2.2.1
创建
maven
项目(这里org是一个域名跟.com和.NET地位相同,同为顶级域名之一)
2.2.2
引入
maven
依赖
pom.xml
<!--spring的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
2.2.3
定义接口与实体类
接口
package com.zsz.service;
public interface SomeService {
void doSome();
}
实现类(查看一个接口的实现类Ctrl+H)
package com.zsz.service.impl;
import com.zsz.service.SomeService;
public class SomeServiceImpl implements SomeService {
public SomeServiceImpl() {
System.out.println("SomeServiceImpl的无参数构造方法");
}
@Override
public void doSome() {
System.out.println("执行了SomeServiceImpl的doSome()方法");
}
}
2.2.4
创建
Spring
配置文件
在
src/main/resources/
目录现创建一个
xml
文件,文件名可以随意,但
Spring 建议的名
称为
applicationContext.xml
。(但是我创建了一个beans.xml)
spring
配置中需要加入约束文件才能正常使用,约束文件是
xsd
扩展名。
<?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">
<!--告诉spring创建对象
声明bean,就是告诉spring要创建某个类的对象
id:对象的自定义名称,唯一值。spring通过这个名称找到对象。
class:类的全限定名称(不能是接口应为spring是反射机制创建对象,必须使用类)
-->
<bean id="someService" class="com.zsz.service.impl.SomeServiceImpl"></bean>
<bean id="someService1" class="com.zsz.service.impl.SomeServiceImpl"></bean>
<!--
spring能创建一个非自定义类的对象么?创建一个存在的某个类的对象。
(可以)
-->
<bean id="myDate" class="java.util.Date"></bean>
</beans>
<!--
spring的配置文件
1.beans:是根标签,spring把java对象成为bean。
2.spring-beans.xsd 是约束文件,和mybatis指定 dtd是一样的。
-->
2.2.5
定义测试类
/**
* spring创建对象的时间:在创建spring的容器时,会创建配置文件中的所有的对象。
* spring创建对象:默认调用的是无参数构造方法
*/
public class MyTest {
@Test
public void test01(){
SomeService someService = new SomeServiceImpl();
someService.doSome();
}
@Test
public void test02(){
// 使用spring容器创建对象
//1.指定spring配置文件的名称
String config="beans.xml";
//2.创建表示spring容器的对象,ApplicationContext
//ApplicationContext就是表示spring容器,通过容器获取对象了。
//Ctrl+H键查看接口的实现类
//ClassPathXmlApplicationContext:表示从类路径中加载spring的配置文件
ApplicationContext ac =new ClassPathXmlApplicationContext(config);
//从容器中获取某个对象,你要调用对象的方法
//getBean("配置文件中的baan的ID值")
SomeService someService = (SomeService) ac.getBean("someService");
//使用spring创建好的对象
someService.doSome();
}
/**
* 获取spring容器中java对象的信息
*/
@Test
public void test03(){
String config="beans.xml";
ApplicationContext ac=new ClassPathXmlApplicationContext(config);
//使用spring提供的方法,获取容器中定义的对象的数量
int count=ac.getBeanDefinitionCount();
System.out.println("spring容器中的对象数量是:"+count);
//容器中每个定义对象的名称
String [] names= ac.getBeanDefinitionNames();
for (String name:names) {
System.out.println("spring容器中的对象的名称是"+name);
}
}
2.2.6
使用
spring
创建非自定义类对象
在beans.xml文件中加入java.util.Date:
<!--
spring能创建一个非自定义类的对象么?创建一个存在的某个类的对象。
(可以)
-->
<bean id="myDate" class="java.util.Date"></bean>
创建测试类:
//获取一个非自定义的类的对象
@Test
public void test04(){
String config="beans.xml";
ApplicationContext ac= new ClassPathXmlApplicationContext(config);
Date myDate = (Date) ac.getBean("myDate");
System.out.println("Date:"+myDate);
int count = ac.getBeanDefinitionCount();
String[] names = ac.getBeanDefinitionNames();
for (String name: names){
System.out.println("spring容器中的对象的名称是"+name);
}
System.out.println("spring容器中的对象数量是:"+count);
}
2.2.7
容器接口和实现类
ApplicationContext
接口(容器)
ApplicationContext
用于加载
Spring
的配置文件,在程序中充当“容器”的角色。其实现
类有两个。
A
、配置文件在类路径下
若
Spring
配置文件存放在项目的类路径下,则使用
ClassPathXmlApplicationContext
实现
类进行加载。
什么是项目的类路径? (生成的target目录下的classes目录中的文件都可以扫描到)
B
、
ApplicationContext 容器中对象的装配时机
ApplicationContext
容器,会在容器对象初始化时,将其中的所有对象一次性全部装配好。
以后代码中若要使用到这些对象,只需从内存中直接获取即可。执行效率较高。但占用内存。
1.spring创建的时间在创建spring的容器时,会创建配置文件的所有对象。
2.spring创建对象:默认调用的是无参数构造方法。
String config="beans.xml";
ApplicationContext ac= new ClassPathXmlApplicationContext(config);
C
、 使用
spring
容器创建的
java
对象
补充一下
项目的类路径:如果spring的配置文件并不直接放在classes包下而是放在了他的子包中,那么他的路径应该这样写:
String config="ba01/applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
错误写法:
String config="applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
报错信息:
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [applicationContext.xml]; nested exception is java.io.FileNotFoundException: class path resource [applicationContext.xml] cannot be opened because it does not exist