Spring - BeanFactory与ApplicationContext介绍

Spring Bean

之前也了解过Spring Bean,但已经忘记了,之后找了一些视频,但是对Spring Bean讲解的不是很全面,现在又重新找了一些视频,对Spring Bean进行一些整理

之前做的笔记:SpringBoot——Bean管理

一、BeanFactory 快速入门

BeanFactory 是Spring整理运行当中最核心的一个对象

1.1 BeanFactory 开发步骤

BeanFactory 不是我们自己写的,是Spring提供的

image-20230602211433750

  • 导入Spring的jar包或Maven坐标
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.7</version>
        </dependency>
    </dependencies>
  • 定义UserService接口及其UserServiceImpl实现类
public class UserServiceImpl implements UserService {
    
    
}
  • 创建beans.xml配置文件,将UserServiceImpl的信息配置到该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">

    <!--class 可以明确Bean在哪-->
    <!--id 为Bean做一个唯一标识-->
    <bean id="userService" class="com.zhangjingqi.service.impl.UserServiceImpl">

    </bean>

</beans>
  • 编写测试代码,创建BeanFactory,加载配置文件,获取UserService实例对象
public class BeanFactoryTest {
    
    
    public static void main(String[] args) {
    
    
//      创建一个工厂对象
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
//      创建一个读取器(读取xml文件)
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
//      读取器读取配置文件,并给工厂
        reader.loadBeanDefinitions("beans.xml");
//      根据id获取Bean实例对象
        Object userService = beanFactory.getBean("userService");
        System.out.println(userService);
    }
}

为什么能产生UserService对象?

​ 因为我们吧UserService对象配置到配置文件中,再通过Bean工厂去加载配置文件

1.2 DI依赖注入

userService对象需要使用到userDao,我们可以将userDao对象配置到userService中

public class UserServiceImpl implements UserService {
    
    
    // BeanFactory去调用该方法,从容器中获得userDao设置到此处
    public void setUserDao(UserDao userDao) {
    
    
        System.out.println(userDao);
    }
}

以配置的方式告知兵工厂

<!--class 可以明确Bean在哪-->
<!--id 为Bean做一个唯一标识-->
<bean id="userService" class="com.zhangjingqi.service.impl.UserServiceImpl">
    <!--name属性就是set方法的名称,并且把set去掉,首字母小写-->
    <!--ref是引用,从容器中找具体需要哪个对象-->
    <property name="userDao" ref="userDao"></property>
</bean>
<!--配置UserDao-->
<bean id="userDao" class="com.zhangjingqi.dao.impl.UserDaoImpl">

</bean>

测试

注意,只创建了一个userService对象,我们下面并没有向控制台中输出东西

//      创建一个工厂对象
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
//      创建一个读取器(读取xml文件)
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
//      读取器读取配置文件,并给工厂
        reader.loadBeanDefinitions("beans.xml");
//      根据id获取Bean实例对象
        Object userService = beanFactory.getBean("userService");

但是控制台中有输出内容,输出的就是UserServiceImpl.setUserDao方法中的内容,set方法我们没有主动调用,是BeanFactory帮我们调用的

image-20230603133742901

说明

property这种配置方式,就是找的UserServiceImpl类下的set方法

<bean id="userService" class="com.zhangjingqi.service.impl.UserServiceImpl">
    <!--name属性就是set方法的名称,并且把set去掉,首字母小写-->
    <!--ref是引用,从容器中找具体需要哪个对象-->
    <property name="userDao" ref="userDao"></property>
</bean>

DI依赖注入总结

  • 定义UserDao接口及其UserDaoImpl实现类;
  • 修改UserServiceImpl代码,添加一个setUserDao(UserDao userDao)用于接收注入的对象;
  • 修改beans.xml配置文件,在UserDaoImpl的<bean>中嵌入<property>配置注入;
  • 修改测试代码,获得UserService时,setUserService方法执行了注入操作

二、ApplicationContext快速入门

2.1 入门

Spring的容器,也叫应用上下文,它底层对于Bean的操作调用的还是BeanFactory

​ 比BeanFactory更常用一些

使用ApplicationContext进行开发时,xml配置文件的名称习惯写成applicationContext.xml

public class ApplicationContextTest {
    
    
    public static void main(String[] args) {
    
    
        //AppletContext是一个接口
        //参数是一个xml配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
        Object userDao = applicationContext.getBean("userDao");
        System.out.println(userDao);
        Object userService = applicationContext.getBean("userService");
        System.out.println(userService);
    }
}

值得我们注意的是

我们下句话执行完成后,便将beans.xml配置文件中的Bean加载到了BeanFactory当中

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");

我们debug一下,下图可以证明

image-20230603141202119

2.2 BeanFactory 与 ApplicationContext关系

  • BeanFactory是Spring早期接口,称为Spring的Bean工厂,ApplicationContext是后期更高级接口,称之为Spring 容器

    BeanFactory主要内部维护的功能是跟Bean产生相关的,是造Bean的

    ApplicationContext内部刨除了Bean工厂功能外,还有其他功能

  • ApplicationContext在BeanFactory基础上对功能进行了扩展,例如:监听功能、国际化功能等。BeanFactory的API更偏向底层,ApplicationContext的API大多数是对这些底层API的封装;

    ApplicationContext的API再去调用BeanFactory中的API

  • Bean创建的主要逻辑和功能都被封装在BeanFactory中,ApplicationContext不仅继承了BeanFactory,而且ApplicationContext内部还维护着BeanFactory的引用,所以,ApplicationContext与BeanFactory既有继承关系,又有融合关系。

image-20230603145647608

  • Bean的初始化时机不同,原始BeanFactory是在首次调用getBean时才进行Bean的创建,而ApplicationContext则是配置文件加载,容器一创建就将Bean都实例化并初始化好

    BeanFactory是延迟加载,getBean时才加载对象,而ApplicationContext直接将对象创建好

2.3 BeanFactory 继承体系

BeanFactory是核心接口,项目运行过程中肯定有具体实现参与,这个具体实现就是DefaultListableBeanFactory,而ApplicationContext内部维护的Beanfactory的实现类也是它

image-20230603151753907

2.4 ApplicationContext 继承体系

只在Spring基础环境下,即只导入spring-context坐标时,此时ApplicationContext的继承体系

image-20230603152421170

实现类 功能描述
ClassPathXmlApplicationContext 加载类路径下的xml配置的ApplicationContext
FileSystemXmlApplicationContext 加载磁盘路径下的xml配置的ApplicationContext
AnnotationConfigApplicationContext 加载注解配置类的ApplicationContext

假如说我们现在在Spring-Web环境下,那继承体系就发生了变化

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-web</artifactId>
   <version>5.3.7</version>
</dependency>

image-20230603153051481

实现类 功能描述
XmlWebApplicationContext web环境下,加载类路径下的xml配置的ApplicationContext
AnnotationConfigWebApplicationContext web环境下,加载磁盘路径下的xml配置的ApplicationContext

猜你喜欢

转载自blog.csdn.net/weixin_51351637/article/details/131025446