Spring源码学习-第一课-IOC容器理论

1、Spring之IOC理论

1.1 IOC的原型

我们程序员不再去管理对象的创建了,更多的去关注业务的实现 ,耦合性大大降低。

public class UserServiceImpl implements UserService {

    private UserDao userDao;
    // 利用set实现  ioc
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void getUser() {
        userDao.getUser();
    }
}

测试:

public class UserGetTest {

    @Test
    public void getUser(){
        UserServiceImpl userService = new UserServiceImpl();
        userService.setUserDao(new UserDaoImpl());
        userService.getUser();

        userService.setUserDao(new UserDaoMysqlImpl());
        userService.getUser();
    }
}
执行结果:
从bean中获取到的用户数据为User{name='hresh'}MySQL数据库中获取到的用户数据为User{name='acorn'}

1.2 IOC的本质

IOC(Inverse of Control:控制反转)是一种设计思想,就是原本需要在程序中手动创建对象的控制权,交给框架来管理。而IOC容器就是Spring实现IOC的载体,IOC容器实际上就是一个Map,Map中存放的是各种创建的对象。

将对象之间的相互依赖关系交给IOC容器管理,并由IOC容器完成相关的注入,将极大简化应用的开发,把程序从复杂的依赖关系中解救出来。IOC容器就像一个工厂,当我们需要创建一个对象的时候,只需要编写相关的注解/配置文件即可,完全不需要考虑如何去创建这个对象。
Spring容器在初始化时先读取配置文件,根据配置文件或者元数据创建对象保存到IOC容器中,当程序需要使用时再从IOC容器中取出所需要的对象。
1、2是保存,3是获取。
采用XML配置Bean的时候,Bean的定义信息和实现是分开的。
而使用注解的方式可以将定义和实现集中到一起(在类上添加相关的注解)

1.3实战分析

1.3.1 使用配置文件实现

1、定义一个User类
@NoArgsConstructor
@AllArgsConstructor
@Data
@Accessors(chain = true)
public class User {

	private String name;
}
2、配置文件配置
<?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">

<!--    配置bean-->
    <bean id="user" class="com.linmain.demo2.bean.User">
        <property name="name" value="hresh" />
    </bean>

</beans>
3、测试类
public class demo2 {

	@Test
	public void getBeanByXml() {
	// 	解析demo2.xml ,得到相关的user文件信息
		ApplicationContext context = new ClassPathXmlApplicationContext("demo2.xml");
	// 	getBean 参数即为bean标签中的id
		User user = (User) context.getBean("user");
		System.out.println(user);
	}
}

运行结果:

User(name=hresh)
思考
  • User 对象是谁创建的?【user 对象是由 Spring 创建的】
  • User 对象的属性是怎么设置的?【user 对象的属性是由 Spring 容器设置的】
  • 这个过程就叫做控制反转:
    控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用 Spring 后,对象是由 Spring 来创建的。
    反转:程序本身不创建对象,而变成被动地接收对象。
  • 依赖注入:利用 set 方法来进行注入的。
  • IOC是一种编程思想,由主动的编程变成被动的接收 。

按照上述的方式我们对之前提到的业务场景进行修改。首先新增 一个 Spring 配置文件 demo3.xml

1.3.2 使用配置文件实现之前的demo的控制反转

1、类
@NoArgsConstructor
@AllArgsConstructor
@Data
@Accessors(chain = true)
public class User {

	private String name;
}
public interface UserDao {


	public void getUser();
}
public class UserDaoImpl implements UserDao {

	@Override
	public void getUser() {
		User test = new User("test");
		System.out.println("从bean中获取到的用户数据为:" + test);
	}
}
public class UserDaoMysqlImpl implements UserDao {


	@Override
	public void getUser() {
		User mysql = new User("mysql");
		System.out.println("从mysql数据库中获取到的用户数据为:"+mysql);
	}
}
public interface UserService {

	public void getUser();
}

public class UserServiceImpl implements UserService {

	private UserDao userDao = new UserDaoMysqlImpl();

	@Override
	public void getUser() {
		userDao.getUser();

	}

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
}
2、配置文件配置
<?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">

    <bean id="mysqlImpl" class="com.linmain.demo1.dao.impl.UserDaoMysqlImpl" />
    <bean id="oracleImpl" class="com.linmain.demo1.dao.impl.UserDaoImpl" />

    <bean id="serviceImpl" class="com.linmain.demo1.service.impl.UserServiceImpl">
        <!--注意: 这里的name并不是属性 , 而是set方法后面的那部分 , 首字母小写   即setUserDao方法-->
        <!--引用另外一个bean , 不是用value 而是用 ref-->
        <property name="userDao" ref="mysqlImpl" />
    </bean>
</beans>
3、测试类
public class demo3 {

	@Test
	public void test() {
		ApplicationContext context = new ClassPathXmlApplicationContext("demo3.xml");
		UserServiceImpl serviceImpl = (UserServiceImpl) context.getBean("serviceImpl");
		serviceImpl.getUser();
	}
}

运行结果:

从mysql数据库中获取到的用户数据为:User(name=mysql)

1.4 IOC创建对象

1.4.1 无参构造器创建

1、类
@Data
@Accessors(chain = true)
public class User {

	private String name;

	public User() {
		System.out.println("无参构造方法");
	}

	public User(String name) {
		System.out.println("有参构造方法");
		this.name = name;
	}
}
2、配置文件
<?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">

<!--    进行无参构造器的ioc-->
    <bean id="user" class="com.linmain.demo4.bean.User">
        <property name="name" value="hresh" />
    </bean>

</beans>
3、测试
public class demo4 {

	@Test
	public void test() {
		// 解析xml配置文件,生成管理相应的bean对象
		ApplicationContext context = new ClassPathXmlApplicationContext("demo4.xml");

	// 	在执行getBean的时候,user已经创建好了,属性是通过set方法注入的
		User user = (User) context.getBean("user");
		System.out.println(user);
	}
}

运行结果:

无参构造方法
User(name=hresh)

1.4.2 有参构造器创建

1、类
@Data
@Accessors(chain = true)
public class User {

	private String name;

	public User() {
		System.out.println("无参构造方法");
	}

	public User(String name) {
		System.out.println("有参构造方法");
		this.name = name;
	}
}
2、配置文件
<?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">

<!--    有参构造方法-->

    <bean id="user" class="com.linmain.demo4.bean.User">
        <constructor-arg name="name" value="youcan"/>
    </bean>
</beans>
3、测试
public class demo5 {


	@Test
	public void test() {
		// 解析xml配置文件,生成管理相应的bean对象
		ApplicationContext context = new ClassPathXmlApplicationContext("demo5.xml");

		// 	在执行getBean的时候,user已经创建好了,属性是通过set方法注入的
		User user = (User) context.getBean("user");
		System.out.println(user);
	}
}

运行结果:

有参构造方法
User(name=youcan)

1.5 IOC涉及到的组件概括

在上面的测试中我们使用到的是ApplicationContext(应用上下文),具体实现是使用ClassPathXmlApplicationContext。我们在此分析一下ClassPathXmlApplicationContext的关系图(实线实现,虚线继承)
在这里插入图片描述在这里插入图片描述此图涉及了IOC容器在spirng中绝大部分的核心类,下面将简单讲解下主要的六大类型

1、Resource

Resource主要是实现了对资源的定义,它的实现类代表了对特定资源的特定访问策略。
如 ClasspathResource 、 URLResource ,FileSystemResource 等
在这里插入图片描述

2、ResourceLoader

有了资源之后,就需要有资源加载模块,Spring使用ResourceLoader 来实现对资源的加载。
在这里插入图片描述

3、BeanFactory

资源加载完毕之后就需要使用BeanFactory 进行加载解析了。它是一个Bean容器,它内部维护着一个BeanDefinition map,并可根据BeanDefinition 的描述进行bean的创建和管理。
BeanFacoty 有三个直接子类 ListableBeanFactoryHierarchicalBeanFactoryAutowireCapableBeanFactoryDefaultListableBeanFactory 为最终默认实现,它实现了所有接口。在这里插入图片描述

4、BeanDefiniBeanFation

BeanDefinition 用来描述Spring容器中的Bean对象。
在这里插入图片描述

5、BeanDefinitionReader

而BeanDefinitionReader 就是起到读取配置文件将其转化成BeanDefinition 保存起来的作用了。
在这里插入图片描述

6、ApplicationContext

ApplicationContext是个Spring容器,也叫做应用上下文,它继承了BeanFactory ,同时也是BeanFactory 的Plus版,结构决定了它和BeanFactory 的功能不同,主要区别有:

  • 继承 MessageSource ,提供国际化的标准访问策略;
  • 继承 ApplicationEventPublisher,提供强大的事件机制;
  • 扩展 ResourceLoader,可以用来加载多个 Resource,可以灵活访问不同的资源;
  • 对 Web 应用的支持。
    在这里插入图片描述
    在这里插入图片描述

1.6 Spring中XML配置

1.6.1 别名alias

alias:为bean设置别名,可以设置多个别名

<!--设置别名:在获取Bean的时候可以使用别名获取-->
<alias name="userT" alias="userNew"/>

1.6.2 Bean的配置

<!--bean就是java对象,由Spring创建和管理-->

<!--
    id 是bean的标识符,要唯一,如果没有配置id,name就是默认标识符
    如果配置id,又配置了name,那么name是别名
    name可以设置多个别名,可以用逗号,分号,空格隔开
    如果不配置id和name,可以根据applicationContext.getBean(.class)获取对象;

    class是bean的全限定名=包名+类名
-->
<bean id="hello" name="hello2 h2,h3;h4" class="com.msdn.bean.Hello">
    <property name="name" value="Spring"/>
</bean>

1.6.3 import

当有多个关于 bean 定义的文件,最后可以集中在一个文件中。

<import resource="{path}/beans.xml"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring IOC容器Spring框架的核心部分之一,它负责管理和组织应用程序中的各种组件。IOC是控制反转的意思,它实现了依赖注入(DI)的思想。DI是指通过容器来管理和注入组件的依赖关系,而不是手动在代码中创建和管理这些组件。当应用程序需要使用某个组件时,可以直接向IOC容器索取该组件,而不需要自己手动创建或管理。 在Spring中,IOC容器负责管理和组织各种Bean。Bean是Spring中的基本组件,它可以是任何一个Java对象。IOC容器会根据配置文件或注解来实例化、配置和管理这些Bean。它会在应用程序启动时,根据配置文件或注解的定义,创建并初始化所有的Bean,并将它们存储在容器中。当应用程序需要使用某个Bean时,只需向IOC容器索取即可。 Spring提供了多种IOC容器的实现,包括XML配置的ApplicationContext和基于注解的AnnotationConfigApplicationContext等。这些容器提供了丰富的功能,如依赖注入、AOP、事务管理等。通过使用IOC容器,可以实现松耦合、可扩展和可测试的应用程序。引用<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [SpringIOC容器详解,通俗易懂看这一篇就够了](https://blog.csdn.net/qq_45369589/article/details/123095028)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [详解Spring IOC 容器启动流程分析](https://download.csdn.net/download/weixin_38750209/12747162)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值