spring核心概念-----笔记

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功能更强大,他还继承了其他接口,拥有获取环境变量,支持国际化,发布事件和资源获取的功能。

1. HierarchicalBeanFactory:拥有获取父BeanFactory的功能
2. ListableBeanFactory:拥有获取beanNames的功能
3. ResourcePatternResolver:资源加载器,可以一次性获取多个资源(文件资源等等)
4. EnvironmentCapable:可以获取运行时环境(没有设置运行时环境功能)
5. ApplicationEventPublisher:拥有广播事件的功能(没有添加事件监听器的功能)
6. MessageSource:拥有国际化功能

 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技术。

仅个人笔记

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值