1、BeanDefinition
BeanDefinition表示spring中bean的定义,用来描述Bean的各个属性。比如:bean的类型,bean是否单例等等。通常我们在开发时会通过申明式来定义bean:
1、@Compnent,@Service等
2、@Bean
3、<bean/>
而我们还可以通过不常用的编程式来定义bean:
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
AbstractBeanDefinition bd = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
bd.setBeanClass(UserService.class);
applicationContext.registerBeanDefinition("userService", bd);
这里只是一种方式,还有很多方式,当然bd还可以细分成很多种类型bd,如:GenericBeanDefinition,AnnotatedGenericBeanDefinition(被注解的bd),ScannedGenericBeanDefinition(被扫描得到的bd),RootBeanDefinition(合并得到的bd)等
2、BeanDefinitionReader
beanDefinition读取器
2.1 AnnotatedBeanDefinitionReader
可以直接将某个类转换为BeanDefinition
AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(applicationContext);
annotatedBeanDefinitionReader.register(UserService.class);
其register方法底层最终是通过new AnnotatedGenericBeanDefinition(Class)来创建一个bd。
2.2 XmlBeanDefinitionReader
可以解析<bean/>标签
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(applicationContext);
int i = xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml");
2.3 ClassPathBeanDefinitionScanner
它是个扫描器,他的作用和AnnotatedBeanDefinitionReader类似,它可以扫描某个包路径,然后判断某个类上是否存在某个注解(比如:@Component),存在就将该类解析为bd。
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(applicationContext);
scanner.scan("com.xxx");
3、BeanFactory
BeanFactory表示bean工厂,他负责创建bean,并提供bean获取的相关API。其中bean工厂最为重要的实现就是DefaultListableBeanFactory,spring最终也是通过DefaultListableBeanFactory类来实现spring容器的,该类里面提供了我们熟知的beanDefinitionMap属性,它存储了spring容器所有的beanDefinition。而DefaultListableBeanFactory还有其他很多重要的属性,如resolvableDependencies,如果有多个相同的bean class,则他会记录在注入的时候,注入哪个class;否则会报错。
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClass(User.class);
beanFactory.registerBeanDefinition("user", beanDefinition);
System.out.println(beanFactory.getBean("user"));
4、ApplicationContext
ApplicationContext是我们常见的类,而我们对它的理解或多或少,其功能和重要性在spring中不言而喻:
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver
通过ApplicationContext的继承,可以看出,他其实也是一个BeanFactory,但是他比BeanFactory功能更强大,他还继承了其他接口,拥有获取环境变量,支持国际化,发布事件和资源获取的功能。
5、类型转换
在spring源码中,可能遇到将String转换为其他类型的场景,所以在spring源码中提供了一些方便类型转换的技术
5.1PropertyEditor
它其实是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);
}
}
将PropertyEditor注册到spring
@Bean
public CustomEditorConfigurer customEditorConfigurer() {
CustomEditorConfigurer customEditorConfigurer = new CustomEditorConfigurer();
Map<Class<?>, Class<? extends PropertyEditor>> propertyEditorMap = new HashMap<>();
// 表示StringToUserPropertyEditor可以将String转化成User类型,在Spring源码中,如果发现当前
// 对象是String,而需要的类型是User,就会使用该PropertyEditor来做类型转化
propertyEditorMap.put(User.class, StringToUserPropertyEditor.class);
customEditorConfigurer.setCustomEditors(propertyEditorMap);
return customEditorConfigurer;
}
然后就可以通过@Value注解将注解属性值赋值给User对象
@Component
public class UserService {
@Value("rick")
private User user;
public void test() {
System.out.println(user.getName());
}
}
5.2 ConversionService
spring中提供的类型转换服务,他比PropertyEditor更强大
public class StringToUserConvertor implements ConditionalGenericConverter {
@Override
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return sourceType.getType().equals(String.class) && targetType.getType().equals(User.class);
}
@Override
public Set<ConvertiblePair> 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;
}
}
将ConversionService注册到spring容器中
@Bean
public ConversionServiceFactoryBean conversionService() {
ConversionServiceFactoryBean factoryBean = new ConversionServiceFactoryBean();
factoryBean.setConverters(Collections.singleton(new StringToUserConvertor()));
return factoryBean;
}
5.3 TypeConverter
它整合了ConversionService和PropertyEditor的功能,是由spring内部调用的
SimpleTypeConverter typeConverter = new SimpleTypeConverter();
//typeConverter.registerCustomEditor(User.class, new StringToUserPropertyEditor());
DefaultConversionService conversionService = new DefaultConversionService();
conversionService.addConverter(new StringToUserConvertor());
typeConverter.setConversionService(conversionService);
User user = typeConverter.convertIfNecessary("1234", User.class);
System.out.println(user.getName());
6、BeanPostProcessor(干涉bean初始化)
BeanPostProcessor表示bean的后置处理器,即bean在初始化前和初始化后需要执行的处理逻辑,可以通过beanName对某个bean做特殊处理,因此我们可以在spring初始化bean的时候对bean进行加工处理。
@Component
public class RickBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化前");
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化后");
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
7、BeanFactoryPostProcessor
与BeanPostProcessor类似,但是BeanFactoryPostProcessor是干涉BeanFactory创建的过程
@Component
public class RickBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("加工beanFactory");
}
}
8、FactoryBean
FactoryBean是由spring对开发人员提供创建bean的一种方式
@Component("user")
public class RickFactoryBean implements FactoryBean {
@Override
public Object getObject() throws Exception {
return new User();
}
@Override
public Class<?> getObjectType() {
return User.class;
}
}
@Component注解的属性为空时,那么beanName为rickFactoryBean,如果指定了属性值为user,则beanName为user,beanclass为User。以这种方式创建的bean,是不会经过完整的bean的生命周期的,他只会经过bean的初始化。
9、MetadataReader、ClassMetadata、AnnotationMetadata
在spring中需要去解析类的信息,比如类的名称,类的注解等,这些都可以称之为类的元数据,所以spring对类的元数据做了抽象,并提供了一些工具类
SimpleMetadataReaderFactory readerFactory = new SimpleMetadataReaderFactory();
MetadataReader metadataReader = readerFactory.getMetadataReader("com.xxx.xxx");
ClassMetadata classMetadata = metadataReader.getClassMetadata();
System.out.println(classMetadata.getClassName());
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
Set<String> annotationTypes = annotationMetadata.getAnnotationTypes();
annotationTypes.forEach(type -> {
System.out.println(type);
});
需要注意的是,SimpleMetadataReader解析类是用的ASM技术
spring在启动的时候需要扫描类,扫描得到的类不会立即加载到jvm中,因为如果指定的包路径比较宽泛,那么会得到很多类,这样一次性加载的jvm会不太好,所以使用ASM技术。
仅个人笔记