spring几个核心概念

1 BeanDefinition

spring里面一个bean的定义类就是BeanDefinition,在spring中,我们可以如下定义一个Bean:

  1. @Bean
  2. @Component(@Service, @Controller)

还有可以通过Spring提供给我们的API的编程式地定义一个BeanDefinition:

private static void beanDefinitionTest() {
   AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
   AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
   beanDefinition.setBeanClass(AppConfig.class);
   beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
   applicationContext.registerBeanDefinition("appConfig", beanDefinition);
   beanDefinition.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE); // 设置自动装配模型
   // 根据BeanDefinition来产生bean对象
   applicationContext.refresh();
   System.out.println(applicationContext.getBean("appConfig"));
}

2 BeanDefinitionReader

从名字来看,BeanDefinitionReader就是读取BeanDefinition的工具,BeanDefinition是一个接口,具体的从哪里读取就要看他具体的实现类:

spring几个核心概念_第1张图片
image-20210124223015083

2.1 XmlBeanDefinition

XmlBeanDefinitionReader就是从读取Xml里面的配置,然后生成BeanDefinition.

private static void xmlBeanDefinitionTest() {
   AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
   XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(applicationContext);
   int i = reader.loadBeanDefinitions("spring.xml");
   System.out.println(i);
}

2.2 AnnotatedBeanDefinitionReader

AnnotatedBeanDefinitionReader是解析一个类其他的注解,然后生成一个AnnotatedBeanDefinition.

private static void annotatedBeanDefinitionTest() {
   AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
   AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(applicationContext);
   // 不管Person.class这个类上面有没有Component注解都会解析其他注解,比如@Scope和@Lazy等
   reader.register(Person.class);
   applicationContext.refresh();
   System.out.println(applicationContext.getBean("person"));
}

2.3 ClassPathBeanDefinitionScanner

ClassPathBeanDefinitionScanner是指定一个包路径,然后进行扫描,获取beanDefinition,接着用refresh就可以把实例创建出来。

这里可以扫描@Service和@Component等注解,但是不能扫描@Bean注解

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

2.4 BeanFactory

Spring中比较核心的是BeanFactory的实现类是DefaultListableBeanFactory

我们先从DefaultListableBeanFactory的继承结构说起

spring几个核心概念_第2张图片
image-20210201221042339
  1. AliasRegistry:支持别名功能,一个名字可以对应多个别名,主要的方法如下:

    spring几个核心概念_第3张图片
    image-20210201221324760
    • 注册别名
    • 删除别名
    • 判断这个名字是否别名
    • 指定名字获取别名

    他的一个简单地实现类是:SimpleAliasRegistry(现在不做过多的解读)

  2. BeanDefinitionRegistry:可以注册、保存、移除、获取某个BeanDefinition

    spring几个核心概念_第4张图片
    image-20210201230046563
  3. BeanFactory:Bean工厂,可以根据某个bean的名字、或类型、或别名获取某个Bean对象

    spring几个核心概念_第5张图片
    image-20210201230029923
  4. SingletonBeanRegistry:可以直接注册、获取某个单例Bean

    [图片上传失败...(image-528ee7-1614005134434)]

  5. DefaultSingletonBeanRegistry:它是一个类,实现了SingletonBeanRegistry接口,拥有了直接注册、获取某个单例Bean的功能

    spring几个核心概念_第6张图片
    image-20210201225910027
  6. HierarchicalBeanFactory:在BeanFactory的基础上,添加了获取父BeanFactory的功能

    spring几个核心概念_第7张图片
    image-20210201225851202

    有一种场景,如果你在beanFactory里面获取不到一个bean,他会自动从他父beanFactory里面获取这个bean

  7. ListableBeanFactory:在BeanFactory的基础上,增加了其他功能,可以获取所有BeanDefinition的beanNames,可以根据某个类型获取对应的beanNames,可以根据某个类型获取{类型:对应的Bean}的映射关系

    spring几个核心概念_第8张图片
    image-20210201225750651
  8. FactoryBeanRegistrySupport:支持了FactoryBean的功能

    spring几个核心概念_第9张图片
    image-20210201230321107
  9. ConfigurableBeanFactory:在HierarchicalBeanFactory和SingletonBeanRegistry的基础上,添加了设置父BeanFactory、类加载器(表示可以指定某个类加载器进行类的加载)、设置Spring EL表达式解析器(表示该BeanFactory可以解析EL表达式)、设置类型转化服务(表示该BeanFactory可以进行类型转化)、可以添加BeanPostProcessor(表示该BeanFactory支持Bean的后置处理器),可以合并BeanDefinition,可以销毁某个Bean等等功能

  10. AbstractBeanFactory:实现了ConfigurableBeanFactory接口,继承了FactoryBeanRegistrySupport,这个BeanFactory的功能已经很全面了,但是不能自动装配和获取beanNames

  11. ConfigurableListableBeanFactory:继承了ListableBeanFactory、AutowireCapableBeanFactory、ConfigurableBeanFactory

  12. AbstractAutowireCapableBeanFactory:继承了AbstractBeanFactory,实现了AutowireCapableBeanFactory,拥有了自动装配的功能

  13. DefaultListableBeanFactory:继承了AbstractAutowireCapableBeanFactory,实现了ConfigurableListableBeanFactory接口和BeanDefinitionRegistry接口,所以DefaultListableBeanFactory的功能很强大

通过以上分析,我们可以知道,通过DefaultListableBeanFactory我们可以做很多事情,比如:

AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClass(User.class);

DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

// 注册BeanDefinition
beanFactory.registerBeanDefinition("user", beanDefinition);
// 注册别名
beanFactory.registerAlias("user", "user1");
// 注册BeanPostProcessor
beanFactory.addBeanPostProcessor(new LubanBeanPostProcessor());

// 获取Bean对象
System.out.println(beanFactory.getBean("user1"));
// 根据类型获取beanNames
System.out.println(beanFactory.getBeanNamesForType(User.class));

2.5 ApplicationContext

首先ApplicationContext是个接口,可以把它理解为一个特殊的BeanFactory

image-20210222215923730
  1. HierarchicalBeanFactory:拥有获取父BeanFactory的功能

    System.out.println(applicationContext.getParentBeanFactory());
    
  2. ListableBeanFactory:拥有获取beanNames的功能

    System.out.println(applicationContext.getBeanDefinitionNames());
    
  3. ResourcePatternResolver:资源加载器,可以一次性获取多个资源(文件资源等等)

    Resource resource = applicationContext.getResource("spring.xml");
    System.out.println(resource.contentLength());
    
  4. EnvironmentCapable:可以获取运行时环境(没有设置运行时环境功能)

    ConfigurableEnvironment environment = applicationContext.getEnvironment();
    System.out.println(environment.getSystemProperties());
    System.out.println(environment.getSystemEnvironment());
    
  5. ApplicationEventPublisher:拥有广播事件的功能(没有添加事件监听器的功能)

    applicationContext.publishEvent("xxx");
    
  6. MessageSource:拥有国际化功能

    System.out.println(applicationContext.getMessage("test", null, new Locale("")));
    

2.6 AnnotationConfigApplicationContext

spring几个核心概念_第10张图片
image-20210222221514521
  1. ConfigurableApplicationContext:继承了ApplicationContext接口,增加了,添加事件监听器、添加BeanFactoryPostProcessor、设置Environment,获取ConfigurableListableBeanFactory等功能
  2. AbstractApplicationContext:实现了ConfigurableApplicationContext接口
  3. GenericApplicationContext:继承了AbstractApplicationContext,实现了BeanDefinitionRegistry接口,拥有了所有ApplicationContext的功能,并且可以注册BeanDefinition,注意这个类中有一个属性(DefaultListableBeanFactory beanFactory)
  4. AnnotationConfigRegistry:可以单独注册某个为类为BeanDefinition(可以处理该类上的@Configuration注解,已经可以处理@Bean注解),同时可以扫描
  5. AnnotationConfigApplicationContext:继承了GenericApplicationContext,实现了AnnotationConfigRegistry接口,拥有了以上所有的功能

3 类型转换

3.1 PropertyEditor

JDK提供的一个类型转换器

public class StringToUserPropertyEditor extends PropertyEditorSupport implements PropertyEditor {

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        User user = new User();
        user.setName(text);
        this.setValue(user);
    }
}

普通是这样来使用的

StringToUserPropertyEditor propertyEditor = new StringToUserPropertyEditor();
propertyEditor.setAsText("1");
User value = (User) propertyEditor.getValue();
System.out.println(value);

如何向Spring中注册PropertyEditor:

@Bean
public CustomEditorConfigurer customEditorConfigurer() {
    CustomEditorConfigurer customEditorConfigurer = new CustomEditorConfigurer();
    Map, Class> propertyEditorMap = new HashMap<>();
    propertyEditorMap.put(User.class, StringToUserPropertyEditor.class);
    customEditorConfigurer.setCustomEditors(propertyEditorMap);
    return customEditorConfigurer;
}

假设现在有如下Bean:

@Component
public class UserService {

    @Value("true")
    User test;

    public void test() {
        System.out.println(test);
    }
}

那么test属性就能正常的完成属性赋值

3.2 ConversionService

Spring中提供的类型转化服务,它比PropertyEditor更强大

public class StringToUserConverter implements ConditionalGenericConverter {

    @Override
    public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
        return sourceType.getType().equals(String.class) && targetType.getType().equals(User.class);
    }

    @Override
    public Set getConvertibleTypes() {
        return Collections.singleton(new ConvertiblePair(String.class, User.class));
    }

    @Override
    public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
        User user = new User();
        user.setName((String)source);
        return user;
    }
}
DefaultConversionService conversionService = new DefaultConversionService();
conversionService.addConverter(new StringToUserConverter());
User value = conversionService.convert("1", User.class);
System.out.println(value);

如何向Spring中注册ConversionService:

@Bean
public ConversionServiceFactoryBean conversionService() {
    ConversionServiceFactoryBean conversionServiceFactoryBean = new ConversionServiceFactoryBean();
    conversionServiceFactoryBean.setConverters(Collections.singleton(new StringToUserConverter()));

    return conversionServiceFactoryBean;
}

3.3 TypeConverter

整合了PropertyEditor和ConversionService的功能,是Spring内部用的

SimpleTypeConverter typeConverter = new SimpleTypeConverter();
typeConverter.registerCustomEditor(User.class, new StringToUserPropertyEditor());
//typeConverter.setConversionService(conversionService);
User value = typeConverter.convertIfNecessary("1", User.class);
System.out.println(value);

你可能感兴趣的:(spring几个核心概念)