一、Spring容器使用IOC创建管理对象
1、IOC(控制反转)简介
**控制:**对对象的创建及管理
**反转:**控制角色由开发人员转给框架(Spring的IOC容器)
IOC思想基于IOC容器完成,IOC底层就是对象工厂
Spring提供IOC容器实现两种方式(两个接口)
- BeanFactory:IOC容器基本实现,是Spring内部使用的接口,不提供开发人员使用
- 加载配置文件的时候不会创建对象,只有在使用的时候创建
- ApplicationContext:BeanFactory的子接口,提供了更多更强大的功能,一般由开发人员使用
- 加载配置文件的时候就创建对象
2、实现步骤
- 创建maven项目
- 加入maven依赖
- spring的依赖,版本5.3.18
- junit依赖
- 创建类(接口及其实现类)
- 和没有使用框架一样,就是一个普通类
- 创建spring需要使用的配置文件
- 声明类的信息,这些类由spring创建管理
- 测试spring创建的对象
3、项目结构
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>hom.wang</groupId>
<artifactId>st-01-hello-spring</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--spring依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.18</version>
</dependency>
</dependencies>
<build>
</build>
</project>
SomeService.java
package hom.wang.service;
public interface SomeService {
void doSome();
}
SomeServiceImpl.java
package hom.wang.service.impl;
import hom.wang.service.SomeService;
public class SomeServiceImpl implements SomeService {
public SomeServiceImpl() {
System.out.println("SomeServiceImpl构造方法执行");
}
@Override
public void doSome() {
System.out.println("实现了SomeServiceImpl中doSome方法");
}
}
beans.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.xsd">
<!--
告诉spring创建对象
声明bean,就是告诉spring创建某个类的对象
id:对象自定义名称,唯一值,spring通过这个名称找到这个对象
class:类的全限定名称(path+name,不能是接口[反射接口创建实例岂不爆炸?])
spring通过反射机制创建类实例(eq: SomeServiceImpl someService =
(SomeServiceImpl)Class.forName("hom.wang.service.impl.SomeServiceImpl").newInstance() )
spring把创建好的对象放在 Map 中,spring框架有一个 Map 是存储对象的(
eq: springMap.put(id值, 对象实例) :
springMap.put("someService", someService) )
一个bean标签声明一个javabean
-->
<bean id="someService" class="hom.wang.service.impl.SomeServiceImpl" />
<bean id="someService02" class="hom.wang.service.impl.SomeServiceImpl" />
<!--
spring创建一个非自定义类(某个已存在类)的对象
-->
<bean id="myDate" class="java.util.Date" />
</beans>
<!--
spring配置文件
1、beans:根标签,spring把 java 对象称为 bean
2、spring-beans.xsd 是约束文件,和 mybatis 指定 dtd 是一样的
-->
MyTest.java
package hom.wang;
import hom.wang.service.SomeService;
import hom.wang.service.impl.SomeServiceImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Arrays;
public class MyTest {
/**
* 开发正转
*/
@Test
public void test_01() {
SomeService someService = new SomeServiceImpl();
someService.doSome();
}
/**
* springIOC
* 控制反转
* 注:spring默认创建对象的时间:在创建spring容器时,会创建配置文件中的所有对象
*/
@Test
public void test_02() {
//使用spring容器创建对象
//1、指定spring配置文件名称
String config = "beans.xml";
//2、创建spring容器对象:ApplicationContext
// ClassPathXmlApplicationContext表示从类路径中加载spring配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(config);
//3、从容器获取对象并调用其方法
// getBean(配置文件中bean的id)
SomeService someService = (SomeService) applicationContext.getBean("someService");
someService.doSome();
}
/**
* 获取spring容器中java对象的信息
* 注:spring创建对象默认调用无参构造
*/
@Test
public void test_03(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
//获取容器定义对象的数量[powered by spring]
int num = applicationContext.getBeanDefinitionCount();
System.out.println("容器定义对象数量:" + num);
//获取容器定义对象的[powered by spring]
String[] names = applicationContext.getBeanDefinitionNames();
Arrays.stream(names).forEach(System.out::println);
}
}