什么是IOC,作用是什么
IOC的定义( Inversion of Controle, 控制反转),是Spring的核心功能,将我们程序中使用的对象交给Spring 来管理,包括对象创建和销毁,最后在通过依赖注入的方式来实现我们程序的调用等,这可以带来很多好处:
- 资源集中管理,实现资源的可配置和易管理。
- 降低了使用资源双方的依赖程度,也就是我们说的耦合度。
测试SpringIoc项目创建
- Maven 配置:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.7.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
- 创建我们自己的Service
public class UserService {
private String name;
public UserService(){
System.out.println("我是无参构造函数");
}
public UserService(String name) {
this.name = name;
System.out.println("我是带参构造函数 " );
}
public void sayHello(){
System.out.println("Hello, My name is " + name);
}
}
- 创建Spring配置文件: Spring-csdn.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"
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-4.0.xsd ">
<!-- 具体配置后续添加-->
</beans>
- 创建TestUserService:
public class TestUserService {
@Test
public void testIoc(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-csdn.xml");
UserService userService = (UserService) applicationContext.getBean("com.lot.test.UserService");
userService.sayHello();
}
}
Bean 的创建方式:
-
无参构造方式, 在spring-csdn.xml中加入配置:
<!-- 无参构造方式创建 --> <bean class="com.lot.test.UserService"/>
执行 TestUserService.testIoc(),打印为:
我是无参构造函数 Hello, My name is null
-
带参数的构造方式, 在spring-csdn.xml中加入配置:
<!--带参构造方式创建--> <bean class="com.lot.test.UserService"> <constructor-arg name="name" value="张井天" /> </bean>
执行 TestUserService.testIoc(),打印为:
我是带参构造函数 Hello, My name is 张井天
-
在具体工作中,为了简化配置可以加入标签: component-scan ,在xml配置了这个标签后,spring可以自动去扫描base-pack下面或者子包下面的java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类注册为bean
<context:component-scan base-package="com.lot.test" />
执行 TestUserService.testIoc(),将com.lot.test.UserService 修改为 userService,打印为:
我是无参构造函数 Hello, My name is null
SpringIoc 创建Bean流程图
-
Spring的源码比较复杂,下面仅仅是博主的一些认识:
-
Spring 首先加载我们配置的 spring-csdn.xml文件,然后对应每个Bean生成 beanDefinition 保存到 CurrentHashMap中,简略时序图如下:
-
当初始化 beanDefinitionMap后,会继续将beanDefinition 实例化为Bean 保存到 DefaultSingletonBeanRegistry 中属性 singletonObjects中,简略时序图如下:
4. 当我调用getBean时,如果是单例的Bean 会直接从singletonObjects 中获取(懒加载会先创建),非单例时,会根据 beanDefinition中保存的信息重新创建bean,返回给程序。