俗话说“磨刀不误砍柴工”,我们本节教程的目的是对Spring的一些核心概念进行扫盲,避免在进入正题讲解的时候由于某些概念还不理解,影响学习效率。

1、BeanDefination

  • BeanDefination标识Bean定义,用来描述一个Bean的特点,比如:
  • class,表示Bean类型
  • scpoe,表示Bean的作用域,是单例还是原型等
  • lazyInit,表示Bean是不是懒加载
  • initMethodName,表示Bean初始化时要执行的方法
  • destroyMethodName,表示bean销毁时候执行的方法
  • 还有很多……

通过,@Bean,@Component等申明式方式所定义的Bean,最终都会被Spring解析为对应的BeanDefinition对象,并放入Spring容器中。
用法如下:Dog类上边并没有加@Component等注解,我们自定义Beandefination,一样可以将Dog注册为Bean。

  1. public class Dog {
  2. void say() {
  3. System.out.println("hi i am a dog name is wangwang");
  4. }
  5. }
  6. @Configuration
  7. @ComponentScan("com.ioc.tuing.impl")
  8. public class MainStart {
  9. public static void main(String[] args) {
  10. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainStart.class);
  11. AbstractBeanDefinition abstractBeanDefinition =
  12. BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
  13. abstractBeanDefinition.setBeanClass(Dog.class);
  14. context.registerBeanDefinition("dog", abstractBeanDefinition);
  15. Dog dog = (Dog)context.getBean("dog");
  16. dog.say();
  17. }
  18. }

2、BeanDefinitionReader

接下来,我们介绍BeanDefination的读取器:BeanDefinationReader,我们在实际工作中其实用的很少,但是在Spring源码里,用的非常多,相当于Spring源码的基础设施。

  • AnnotatedBeanDefinitionReader

它可以直接把某个类转换为BeanDefinition,并且会解析该类上的注解,比如:Dog类是个普通类,我们可以用AnnotatedBeanDefinitionReader将Dog.class解析为BeanDefinition。注意:它能解析的注解是:@Conditional,@Scope、@Lazy、@Primary、@DependsOn、@Role、@Description

  1. public class Dog {
  2. void say() {
  3. System.out.println("hi i am a dog name is wangwang");
  4. }
  5. }
  6. @Configuration
  7. @ComponentScan("com.ioc.tuing.impl")
  8. public class MainStart {
  9. public static void main(String[] args) {
  10. // AnnotatedBeanDefinitionReader
  11. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainStart.class);
  12. AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(context);
  13. // 将Dog.class解析为BeanDefinition
  14. annotatedBeanDefinitionReader.register(Dog.class);
  15. Dog dog = (Dog)context.getBean("dog");
  16. dog.say();
  17. }
  18. }
  • XmlBeanDefinitionReader

它可以解析标签

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:p="http://www.springframework.org/schema/p"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd">
  7. <bean id="memberXML" class="com.ioc.tuing.impl.MemberXML"></bean>
  8. </beans>
  1. public class MemberXML {
  2. void say() {
  3. System.out.println("i am MemberXML");
  4. }
  5. }
  6. @Configuration
  7. @ComponentScan("com.ioc.tuing.impl")
  8. public class MainStart {
  9. public static void main(String[] args) {
  10. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainStart.class);
  11. XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(context);
  12. // 解析spring.xml里的<bean/>标签
  13. int i = xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml");
  14. MemberXML memberXML = (MemberXML)context.getBean("memberXML");
  15. memberXML.say();
  16. }
  17. }
  • ClassPathBeanDefinitionScanner

ClassPathBeanDefinitionScanner是扫描器,但是它的作用和BeanDefinitionReader类似,它可以进行扫描,扫描某个包路径,对扫描到的类进行解析,比如,扫描到的类上如果存在@Component注解,那么就会把这个类解析为一个BeanDefinition,比如:

  1. public class MainStart {
  2. public static void main(String[] args) {
  3. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
  4. context.refresh();
  5. ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
  6. scanner.scan("com.ioc");
  7. User user = (User)context.getBean("user");
  8. user.say();
  9. }
  10. }

3、BeanFactory

BeanFactory表示Bean工厂,负责创建Bean,并且提供获取Bean的API。
而ApplicationContext是BeanFactory的一种,在Spring源码中,它是这样的:

  1. public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
  2. MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
  3. ......
  4. }

我们发现,ApplicationContext继承了ListableBeabFactory、HierarchicalBeanFactory,而这两个接口都继承自BeanFactory接口。所以,ApplicationContext拥有BeanFactory的所有功能,除此之外还有用其他功能,比如:MessageSource表示国际化,ApplicationEventPublisher表示事件发布,EnvironmentCapable表示获取环境变量,等等。
在Spring源码中,BeanFactory有一个非常重要的实现类:DefaultListableBeanFactory,所以我们可以使用DefaultListableBeanFactory作为容器,而不使用ApplicationContext的实现类作为容器,比如:

  1. @Configuration
  2. @ComponentScan("com.ioc.tuing.impl")
  3. public class MainStart {
  4. public static void main(String[] args) {
  5. DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
  6. AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
  7. beanDefinition.setBeanClass(User.class);
  8. beanFactory.registerBeanDefinition("user", beanDefinition);
  9. User user = (User)beanFactory.getBean("user");
  10. user.say();
  11. }

DefaultListableBeanFactory拥有的功能如下:
image.png

  1. AliasRegistry:支持别名功能,一个名字可以对应多个别名
  2. BeanDefinitionRegistry:可以注册、保存、移除、获取某个BeanDefinition
  3. BeanFactory:Bean工厂,可以根据某个bean的名字、或类型、或别名获取某个Bean对象
  4. SingletonBeanRegistry:可以直接注册、获取某个单例Bean
  5. SimpleAliasRegistry:它是一个类,实现了AliasRegistry接口中所定义的功能,支持别名功能
  6. ListableBeanFactory:在BeanFactory的基础上,增加了其他功能,可以获取所有BeanDefinition的beanNames,可以根据某个类型获取对应的beanNames,可以根据某个类型获取{类型:对应的Bean}的映射关系
  7. HierarchicalBeanFactory:在BeanFactory的基础上,添加了获取父BeanFactory的功能
  8. DefaultSingletonBeanRegistry:它是一个类,实现了SingletonBeanRegistry接口,拥有了直接注册、获取某个单例Bean的功能
  9. ConfigurableBeanFactory:在HierarchicalBeanFactory和SingletonBeanRegistry的基础上,添加了设置父BeanFactory、类加载器(表示可以指定某个类加载器进行类的加载)、设置Spring EL表达式解析器(表示该BeanFactory可以解析EL表达式)、设置类型转化服务(表示该BeanFactory可以进行类型转化)、可以添加BeanPostProcessor(表示该BeanFactory支持Bean的后置处理器),可以合并BeanDefinition,可以销毁某个Bean等等功能
  10. FactoryBeanRegistrySupport:支持了FactoryBean的功能
  11. AutowireCapableBeanFactory:是直接继承了BeanFactory,在BeanFactory的基础上,支持在创建Bean的过程中能对Bean进行自动装配
  12. AbstractBeanFactory:实现了ConfigurableBeanFactory接口,继承了FactoryBeanRegistrySupport,这个BeanFactory的功能已经很全面了,但是不能自动装配和获取beanNames
  13. ConfigurableListableBeanFactory:继承了ListableBeanFactory、AutowireCapableBeanFactory、ConfigurableBeanFactory
  14. AbstractAutowireCapableBeanFactory:继承了AbstractBeanFactory,实现了AutowireCapableBeanFactory,拥有了自动装配的功能
  15. DefaultListableBeanFactory:继承了AbstractAutowireCapableBeanFactory,实现了ConfigurableListableBeanFactory接口和BeanDefinitionRegistry接口,所以DefaultListableBeanFactory的功能很强大

    4、ApplicationContext

    image.png
    上边已经提到过,ApplicationContext继承自BeanFactory,但是它比BeanFactory有更多的功能:

  16. HierarchicalBeanFactory:拥有获取父BeanFactory的功能

  17. ListableBeanFactory:拥有获取beanNames的功能
  18. ResourcePatternResolver:资源加载器,可以一次性获取多个资源(文件资源等等)
  19. EnvironmentCapable:可以获取运行时环境(没有设置运行时环境功能)
  20. ApplicationEventPublisher:拥有广播事件的功能(没有添加事件监听器的功能)
  21. MessageSource:拥有国际化功能

ApplicationContext有两个非常重要的实现类:
AnnotationConfigApplicationContext
image.png
ClassPathXmlApplicationContext
image.png

5、BeanPostProcessor

BeanPostProcessor表示Bean的后置处理器,也可称之为增强器,我们可以自定义一个或多个BeanPostProcessor,例:

  1. @Component
  2. public class MyBeanPostProcess implements BeanPostProcessor {
  3. @Override
  4. public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  5. if ("user".equals(beanName)) {
  6. return bean;
  7. }
  8. System.out.println("postProcessBeforeInitialization" + beanName);
  9. return bean;
  10. }
  11. @Override
  12. public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  13. if ("user".equals(beanName)) {
  14. return bean;
  15. }
  16. System.out.println("postProcessAfterInitialization" + beanName);
  17. return bean;
  18. }
  19. }

一个BeanPostProcessor可以在任意一个Bean初始化之前以及初始化之后去额外的做一些用户自定义的逻辑,当然,我们可以通过判断beanName来进行针对性处理(针对某个Bean,或某部分Bean)。
我们可以通过定义BeanPostProcessor来干涉Spring创建Bean的过程。

6、BeanFactoryPostProcessor

BeanFactoryPostProcessor表示Bean工厂的后置处理器,其实和BeanPostProcessor类似,BeanPostProcessor是干涉Bean的创建过程,BeanFactoryPostProcessor是干涉BeanFactory的创建过程。比如,我们可以这样定义一个BeanFactoryPostProcessor:

  1. @Component
  2. public class MyBeanFactoryPostProcess implements BeanFactoryPostProcessor {
  3. @Override
  4. public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
  5. System.out.println("MyBeanFactoryPostProcessor...postProcessBeanFactory...");
  6. int count = beanFactory.getBeanDefinitionCount();
  7. String[] names = beanFactory.getBeanDefinitionNames();
  8. System.out.println("current BeanFactory have " + count + " Bean");
  9. System.out.println(Arrays.asList(names));
  10. }
  11. }

我们可以在postProcessBeanFactory()方法中对BeanFactory进行加工。