13-容器

一、创建容器

容器(也称为 IoC 容器或 Bean 容器)的创建是 Spring 框架的核心之一,一般有两种创建方式:基于 XML 配置文件和基于注解。

1、基于 XML 配置文件的容器创建

第一步是加载配置文件。Spring 框架会在类路径下搜索所有以“applicationContext”为前缀并以“.xml”结尾的文件,并将它们作为配置文件加载。在配置文件中,我们需要定义各个 Bean 的名称、类型、属性及其依赖关系。

例如,在配置文件 applicationContext.xml 中,我们可以定义一个名为“userService”的 Bean,该 Bean 的类型为 UserServiceImpl,其依赖于名为“userDao”的另一个 Bean,同时还指定了该 Bean 的初始化方法和销毁方法:

<bean id="userService" class="com.example.UserService">
    <property name="userDao" ref="userDao"/>
    <property name="name" value="张三"/>
    <property name="age" value="18"/>
    <init-method init="init"/>
    <destroy-method destroy="destroy"/>
</bean>

<bean id="userDao" class="com.example.UserDao"/>

第二步是使用 Spring 提供的 ApplicationContext 接口加载配置文件并创建容器。ApplicationContext 是一个高级容器,它提供了很多丰富的服务,包括国际化支持、事件传播和 AOP 等。

例如,在 Java 代码中,我们可以使用 ClassPathXmlApplicationContext 类加载 applicationContext.xml 文件,并通过getBean()方法获取名为“userService”的 Bean 实例:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) context.getBean("userService");
        System.out.println(userService.getName());
    }
}

2、基于注解的容器创建

第一步是在 Java 代码中通过注解声明 Bean。在 Spring 4.x 版本之后,支持使用注解来声明 Bean,这样可以使得代码更加简洁和易读。

例如,我们可以在 UserServiceImpl 类上使用@Component注解声明其为一个 Bean,并指定该 Bean 的名称为“userService”:

import org.springframework.stereotype.Component;

@Component("userService")
public class UserServiceImpl {
    ...
}

同时,在 UserDaoImpl 类上也可以使用 @Component 注解声明其为另一个 Bean,并指定该 Bean 的名称为“userDao”:

import org.springframework.stereotype.Component;

@Component("userDao")
public class UserDaoImpl {
    ...
}

第二步是通过 Java 代码创建容器,并将这些 Bean 注册到容器中。在 Spring 中,可以通过 AnnotationConfigApplicationContext 类来实现这一功能:

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.scan("com.example");
        context.refresh();
        
        UserService userService = (UserService) context.getBean("userService");
        System.out.println(userService.getName());
    }
}

在上面的代码中,我们首先创建了一个 AnnotationConfigApplicationContext 对象,并通过scan()方法扫描指定路径下的所有 Bean,然后通过refresh()方法加载并注册这些 Bean 到容器中。最后,我们通过getBean()方法获取名为“userService”的 Bean 实例,并输出其名称。

二、获取bean

1. 基于 XML 配置文件的容器获取 Bean

首先,在 XML 配置文件中定义一个 Bean。例如,我们可以定义一个名为“userService”的 Bean:

<bean id="userService" class="com.example.UserService">
    <property name="userDao" ref="userDao"/>
    <property name="name" value="张三"/>
    <property name="age" value="18"/>
    <init-method init="init"/>
    <destroy-method destroy="destroy"/>
</bean>

<bean id="userDao" class="com.example.UserDao"/>

然后,在 Java 代码中获取该 Bean 的实例。可以使用 ClassPathXmlApplicationContext 类加载配置文件,并调用 getBean() 方法获取 Bean 实例:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) context.getBean("userService");
        System.out.println(userService.getName());
    }
}

在上面的代码中,我们首先创建了一个 ApplicationContext 对象,然后通过 getBean() 方法获取名为“userService”的 Bean 实例,最后输出 userService 的名称。

2. 基于注解的容器获取 Bean

首先,在 Java 代码中声明一个 Bean。例如,我们可以在 UserServiceImpl 类上使用 @Component 注解声明其为一个 Bean,并指定该 Bean 的名称为“userService”:

import org.springframework.stereotype.Component;

@Component("userService")
public class UserServiceImpl {
    ...
}

然后,在 Java 代码中获取该 Bean 的实例。可以使用 AnnotationConfigApplicationContext 类加载配置文件,并调用 getBean() 方法获取 Bean 实例:

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.scan("com.example");
        context.refresh();
        
        UserService userService = (UserService) context.getBean("userService");
        System.out.println(userService.getName());
    }
}

在上面的代码中,我们首先创建了一个 AnnotationConfigApplicationContext 对象,并通过 scan() 方法扫描指定路径下的所有 Bean,然后通过 refresh() 方法加载并注册这些 Bean 到容器中。最后,我们通过 getBean() 方法获取名为“userService”的 Bean 实例,并输出其名称。

三、容器类层次结构

在 Spring 中,容器类层次结构是一种管理和组织 Bean 的方式。这种层次结构由多个 BeanFactory 实例构成,每个 BeanFactory 实例都可以管理一组 Bean,并且它们可以相互嵌套,形成父子关系的层次结构。

Spring 提供了多个接口来实现这种层次结构,其中最常用的包括:

  1. BeanFactory:所有 BeanFactory 实现的顶层接口,提供了基本的 Bean 容器的功能,如 Bean 的加载、实例化和依赖注入等。

  2. ListableBeanFactory:继承了 BeanFactory 接口,提供了额外的功能,允许我们以编程方式查找和枚举容器中所有的 Bean。

  3. HierarchicalBeanFactory:继承了 ListableBeanFactory 接口,添加了支持父子 BeanFactory 层次结构的能力。

  4. ApplicationContext:继承自 ListableBeanFactory 接口,是 BeanFactory 接口的超集,提供了更多应用级别的服务,例如国际化消息解析、事件发布、AOP 功能等。

  5. ConfigurableApplicationContext:继承自 ApplicationContext 接口,添加了对上下文配置的可编辑性,允许我们在应用程序运行时对 Bean 进行修改。

  6. WebApplicationContext:用于 Web 应用程序的 ApplicationContext,提供了特定于 Web 应用程序的服务。

容器类层次结构中的每个 BeanFactory 实例都有一个父级 BeanFactory,它可以作为容器类层次结构中的子容器,这种关系通常被称为父子容器。子容器可以通过委托其父级容器来查找 Bean,如果父级容器无法找到所需的 Bean,则子容器自己会尝试进行查找。

四、BeanFactory

BeanFactory 是所有 Spring 容器架构的基础,它定义了一组基本的方法,允许我们加载、实例化和管理 Bean 对象。BeanFactory 的主要作用是提供了简单的 Bean 实例化功能,并管理 Bean 的依赖注入和配置。

BeanFactory 最重要的方法包括:

1. getBean(String name):根据 Bean 的名称获取 Bean 实例。

2. getBean(Class<T> requiredType):根据 Bean 的类型获取 Bean 实例。

3. containsBean(String name):判断容器是否包含指定名称的 Bean。

4. isSingleton(String name):判断指定名称的 Bean 是否为单例模式。

5. getType(String name):返回指定名称的 Bean 的类型。

6. getAliases(String name):返回指定名称的 Bean 的别名。

除了上述方法外,它还提供了 Bean 生命周期的支持,允许我们在 Bean 实例化之前或之后执行定制逻辑,例如 BeanPostProcessor 和 BeanFactoryPostProcessor。

Spring 中有多种实现了 BeanFactory 接口的类,包括:

1. XmlBeanFactory:最早的 BeanFactory 实现类,在 Spring 3.1 版本已经被废弃。

2. DefaultListableBeanFactory:是 Spring 默认的 BeanFactory 实现,在大多数情况下都可以满足需求。它可以用于加载一般的 XML 配置文件,同时也可以通过编程方式注册 Bean。

3. GenericApplicationContext:是 ApplicationContext 接口的默认实现,同时也实现了 BeanFactory 接口,因此它可以作为一个简单的 BeanFactory 使用。与 DefaultListableBeanFactory 相比,GenericApplicationContext 还支持 Annotation 驱动的配置和自动扫描组件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值