Spring-IoC的概念和配置(JavaConfig为例)

BeanFactory & ApplicationContext

IoC(DI) IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies, that is, the other objects they work with, only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method.
Spring通过一个配置文件描述Bean与Bean之间的依赖关系,利用Java语言的反射功能实例化Bean并建立Bean之间的依赖关系。同时,Spring还提供了Bean实例缓存、声明周期管理、Bean实例代理、事件发布、资源装载等高级服务
org.springframework.beansorg.springframework.context包是IoC容器的基础。BeanFactory是Spring框架最核心的接口,它提供了高级Ioc的配置机制。ApplicationContextBeanFactory的子接口,提供了更多面向应用的功能。一般称BeanFactory为IoC容器,而ApplicationContext为应用上下文,详细介绍参考这里

BeanFactory

Spring 定义的Bean比JavaBean的定义更宽泛,可以说所有可以被Spring容器实例化并管理的Java类都可以成为Bean。BeanFactory的类体系结构如下:
BeanFactory类体系结构

ApplicationContext

ApplicationContext的主要实现类是ClassPathXmlApplicationContextFileSystemXmlApplicationContext,前者默认从类路径加载配置文件,后者默认从文件系统加载配置文件。

ApplicationContext还扩展了很多有用的接口:

  • ApplicationEventPublisher——让容器拥有发布应用上下文事件的功能,包括容器启动事件、关闭事件。实现ApplicationListener事件监听接口的Bean可以接收到容器的事件,并对事件进行相应处理。在ApplicationContext的实现类AbstractApplicationContext中存在一个ApplicationEventMulticaster,它负责保存所有的监听器,以便在容器产生上下文事件时通知这些监听者。
  • MessageResource——用于国际化
  • ResourcePatternResolver——可以通过带前缀的Ant风格的资源文件路径装载Spring的配置文件。
  • LifeCycle——该接口提供了start()stop()两个方法,主要用于控制异步处理过程。

ConfigurableApplicationContext新增了两个主要的方法:refresh()close(),让ApplicationContext具有启动、刷新和关闭应用上下文的能力。

ApplicationContext的初始化和BeanFactory有一个重大区别:BeanFactory在初始化容器时,并未实例化Bean,直到第一次访问某个Bean时才实例化目标Bean;ApplicationContext则在初始化应用上下文时就实例化所有的单例Bean。

Spring为基于注解类的配置提供了专门的ApplicationContext实现类:AnnotationConfigApplicationContext

WebApplicationContext

WebApplicationContext允许从相对于Web根目录的路径中加载配置文件完成初始化工作。从WebApplicationContext中可以获取ServletContext的引用,整个WebApplicationCOntext对象作为属性放置在ServletContext中,以便Web应用环境可以访问Spring应用上下文。

Bean

在容器内部,bean的定义通过BeanDefinition对象表示,BeanDefinition对象主要包括的bean的元数据如下:

  1. 类的全限定名——实际的类名
  2. bean的行为配置,如bean的作用域、生命周期回调函数等
  3. 对其它bean的引用,这些引用也称为合作者或依赖
  4. 其它设置信息

基于JavaConfig的容器配置

Spring IoC通过配置元数据的方式告诉Spring容器实例化、配置并装配对象。配置元数据主要分两种:
1. XML模式。XML模式实现了配置文件和代码的分离,开发者编写的是最纯粹的POJO。缺点是配置文件冗长,不易维护。
2. JavaConfig。JavaConfig通过注解的形式来实现通过Java代码配置容器的目的。
Spring 还支持混用这两种配置方式,本文主要以JavaConfig配置为主。

@Bean方法不是声明在@Configuration类之中时,这种bean会被通过轻量级模式处理,在这种情况下,@Bean方法不应该调用其它的@Bean方法。只有@Configuration类中的@Bean方法才能调用其它@Bean方法,这样能避免同一个@Bean方法被多次调用,防止出现意想不到的bug。参考这里
在JavaConfig中,最核心的是@Configuration类和@Bean方法。
@Beean注解用于表明被注解的方法会实例化、配置并且初始化一个能被Spring IoC容器管理的新对象。这个注解与XML配置的<bean/>效果相同。@Bean主要用于@Configuration类中,原因如上所述。@Configuration注解用于表明被注解的类主要是作为bean definition的源文件而存在的,而且@Configuration还允许内部bean之间的依赖,只需要调用其它的@Bean方法即可。

通过AnnotationConfigApplicationContext实例化Spring Container

AnnotationConfigApplicationContext能同时接受@Configuration@Component以及JSR-330元数据注解作为输入。
@Configuration类作为输入时,@Configuration类自身会被作为bean definition被注册,所有@Bean方法也会作为bean definition注册。

简单的构造器

@Configuration类作为输入

public static void main(String[] args) {
  ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
  MyService myService = ctx.getBean(MyService.class);
  myService.doStuff();
}

@Component或JSR-330注解的类作为输入

public static void main(String[] args) {
  ApplicationContext ctx = new AnnotationConfigApplicationContext(MyServiceImpl.class, Dependency1.class, Dependency2.class);
  MyService myService = ctx.getBean(MyService.class);
  myService.doStuff();
}

通过register(Class< ? >…)方法以编程的方式构建容器

public static void main(String[] args) {
  AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
  ctx.register(AppConfig.class, OtherConfig.class);
  ctx.register(AdditionalConfig.class);
  ctx.refresh();
  MyService myService = ctx.getBean(MyService.class);
  myService.doStuff();
}

通过scan(String…)方法实现组件扫描

public static void main(String[] args) {
  AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
  ctx.scan("com.acme");
  ctx.refresh();
  MyService myService = ctx.getBean(MyService.class);
}

通过AnnotationConfigWebApplicationContext支持Web Application

当配置Spring ContextLoaderListenerservlet监听器, Spring DispatcherServlet等组件时会用到这个实现。关于Spring MVC的配置请移步这里。

获取生命周期回调

所有带有@Bean的类定义都支持常规的声明周期回调函数,还能使用JSR-250注解。

组合基于Java的配置类

通过@Import注解实现:

@Configuration
public class ConfigA {
  public @Bean A a() { return new A(); }
}

@Configuration
@Import(ConfigA.class)
public class ConfigB {
  public @Bean B b() { return new B(); }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值