俗话说“磨刀不误砍柴工”,我们本节教程的目的是对Spring的一些核心概念进行扫盲,避免在进入正题讲解的时候由于某些概念还不理解,影响学习效率。
1、BeanDefination
- BeanDefination标识Bean定义,用来描述一个Bean的特点,比如:
- class,表示Bean类型
- scpoe,表示Bean的作用域,是单例还是原型等
- lazyInit,表示Bean是不是懒加载
- initMethodName,表示Bean初始化时要执行的方法
- destroyMethodName,表示bean销毁时候执行的方法
- 还有很多……
通过
用法如下:Dog类上边并没有加@Component等注解,我们自定义Beandefination,一样可以将Dog注册为Bean。
public class Dog {void say() {System.out.println("hi i am a dog name is wangwang");}}@Configuration@ComponentScan("com.ioc.tuing.impl")public class MainStart {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainStart.class);AbstractBeanDefinition abstractBeanDefinition =BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();abstractBeanDefinition.setBeanClass(Dog.class);context.registerBeanDefinition("dog", abstractBeanDefinition);Dog dog = (Dog)context.getBean("dog");dog.say();}}
2、BeanDefinitionReader
接下来,我们介绍BeanDefination的读取器:BeanDefinationReader,我们在实际工作中其实用的很少,但是在Spring源码里,用的非常多,相当于Spring源码的基础设施。
- AnnotatedBeanDefinitionReader
它可以直接把某个类转换为BeanDefinition,并且会解析该类上的注解,比如:Dog类是个普通类,我们可以用AnnotatedBeanDefinitionReader将Dog.class解析为BeanDefinition。注意:它能解析的注解是:@Conditional,@Scope、@Lazy、@Primary、@DependsOn、@Role、@Description
public class Dog {void say() {System.out.println("hi i am a dog name is wangwang");}}@Configuration@ComponentScan("com.ioc.tuing.impl")public class MainStart {public static void main(String[] args) {// AnnotatedBeanDefinitionReaderAnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainStart.class);AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(context);// 将Dog.class解析为BeanDefinitionannotatedBeanDefinitionReader.register(Dog.class);Dog dog = (Dog)context.getBean("dog");dog.say();}}
- XmlBeanDefinitionReader
它可以解析
<?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:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="memberXML" class="com.ioc.tuing.impl.MemberXML"></bean></beans>
public class MemberXML {void say() {System.out.println("i am MemberXML");}}@Configuration@ComponentScan("com.ioc.tuing.impl")public class MainStart {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainStart.class);XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(context);// 解析spring.xml里的<bean/>标签int i = xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml");MemberXML memberXML = (MemberXML)context.getBean("memberXML");memberXML.say();}}
- ClassPathBeanDefinitionScanner
ClassPathBeanDefinitionScanner是扫描器,但是它的作用和BeanDefinitionReader类似,它可以进行扫描,扫描某个包路径,对扫描到的类进行解析,比如,扫描到的类上如果存在@Component注解,那么就会把这个类解析为一个BeanDefinition,比如:
public class MainStart {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();context.refresh();ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);scanner.scan("com.ioc");User user = (User)context.getBean("user");user.say();}}
3、BeanFactory
BeanFactory表示Bean工厂,负责创建Bean,并且提供获取Bean的API。
而ApplicationContext是BeanFactory的一种,在Spring源码中,它是这样的:
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,MessageSource, ApplicationEventPublisher, ResourcePatternResolver {......}
我们发现,ApplicationContext继承了ListableBeabFactory、HierarchicalBeanFactory,而这两个接口都继承自BeanFactory接口。所以,ApplicationContext拥有BeanFactory的所有功能,除此之外还有用其他功能,比如:MessageSource表示国际化,ApplicationEventPublisher表示事件发布,EnvironmentCapable表示获取环境变量,等等。
在Spring源码中,BeanFactory有一个非常重要的实现类:DefaultListableBeanFactory,所以我们可以使用DefaultListableBeanFactory作为容器,而不使用ApplicationContext的实现类作为容器,比如:
@Configuration@ComponentScan("com.ioc.tuing.impl")public class MainStart {public static void main(String[] args) {DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();beanDefinition.setBeanClass(User.class);beanFactory.registerBeanDefinition("user", beanDefinition);User user = (User)beanFactory.getBean("user");user.say();}
DefaultListableBeanFactory拥有的功能如下:
- AliasRegistry:支持别名功能,一个名字可以对应多个别名
- BeanDefinitionRegistry:可以注册、保存、移除、获取某个BeanDefinition
- BeanFactory:Bean工厂,可以根据某个bean的名字、或类型、或别名获取某个Bean对象
- SingletonBeanRegistry:可以直接注册、获取某个单例Bean
- SimpleAliasRegistry:它是一个类,实现了AliasRegistry接口中所定义的功能,支持别名功能
- ListableBeanFactory:在BeanFactory的基础上,增加了其他功能,可以获取所有BeanDefinition的beanNames,可以根据某个类型获取对应的beanNames,可以根据某个类型获取{类型:对应的Bean}的映射关系
- HierarchicalBeanFactory:在BeanFactory的基础上,添加了获取父BeanFactory的功能
- DefaultSingletonBeanRegistry:它是一个类,实现了SingletonBeanRegistry接口,拥有了直接注册、获取某个单例Bean的功能
- ConfigurableBeanFactory:在HierarchicalBeanFactory和SingletonBeanRegistry的基础上,添加了设置父BeanFactory、类加载器(表示可以指定某个类加载器进行类的加载)、设置Spring EL表达式解析器(表示该BeanFactory可以解析EL表达式)、设置类型转化服务(表示该BeanFactory可以进行类型转化)、可以添加BeanPostProcessor(表示该BeanFactory支持Bean的后置处理器),可以合并BeanDefinition,可以销毁某个Bean等等功能
- FactoryBeanRegistrySupport:支持了FactoryBean的功能
- AutowireCapableBeanFactory:是直接继承了BeanFactory,在BeanFactory的基础上,支持在创建Bean的过程中能对Bean进行自动装配
- AbstractBeanFactory:实现了ConfigurableBeanFactory接口,继承了FactoryBeanRegistrySupport,这个BeanFactory的功能已经很全面了,但是不能自动装配和获取beanNames
- ConfigurableListableBeanFactory:继承了ListableBeanFactory、AutowireCapableBeanFactory、ConfigurableBeanFactory
- AbstractAutowireCapableBeanFactory:继承了AbstractBeanFactory,实现了AutowireCapableBeanFactory,拥有了自动装配的功能
DefaultListableBeanFactory:继承了AbstractAutowireCapableBeanFactory,实现了ConfigurableListableBeanFactory接口和BeanDefinitionRegistry接口,所以DefaultListableBeanFactory的功能很强大
4、ApplicationContext

上边已经提到过,ApplicationContext继承自BeanFactory,但是它比BeanFactory有更多的功能:HierarchicalBeanFactory:拥有获取父BeanFactory的功能
- ListableBeanFactory:拥有获取beanNames的功能
- ResourcePatternResolver:资源加载器,可以一次性获取多个资源(文件资源等等)
- EnvironmentCapable:可以获取运行时环境(没有设置运行时环境功能)
- ApplicationEventPublisher:拥有广播事件的功能(没有添加事件监听器的功能)
- MessageSource:拥有国际化功能
ApplicationContext有两个非常重要的实现类:
AnnotationConfigApplicationContext
ClassPathXmlApplicationContext
5、BeanPostProcessor
BeanPostProcessor表示Bean的后置处理器,也可称之为增强器,我们可以自定义一个或多个BeanPostProcessor,例:
@Componentpublic class MyBeanPostProcess implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if ("user".equals(beanName)) {return bean;}System.out.println("postProcessBeforeInitialization" + beanName);return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if ("user".equals(beanName)) {return bean;}System.out.println("postProcessAfterInitialization" + beanName);return bean;}}
一个BeanPostProcessor可以在任意一个Bean的初始化之前以及初始化之后去额外的做一些用户自定义的逻辑,当然,我们可以通过判断beanName来进行针对性处理(针对某个Bean,或某部分Bean)。
我们可以通过定义BeanPostProcessor来干涉Spring创建Bean的过程。
6、BeanFactoryPostProcessor
BeanFactoryPostProcessor表示Bean工厂的后置处理器,其实和BeanPostProcessor类似,BeanPostProcessor是干涉Bean的创建过程,BeanFactoryPostProcessor是干涉BeanFactory的创建过程。比如,我们可以这样定义一个BeanFactoryPostProcessor:
@Componentpublic class MyBeanFactoryPostProcess implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println("MyBeanFactoryPostProcessor...postProcessBeanFactory...");int count = beanFactory.getBeanDefinitionCount();String[] names = beanFactory.getBeanDefinitionNames();System.out.println("current BeanFactory have " + count + " Bean");System.out.println(Arrays.asList(names));}}
我们可以在postProcessBeanFactory()方法中对BeanFactory进行加工。
