马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
目次
ApplicationContext
AnnotationConfigApplicationContext
ClassPathXmlApplicationContext
范例转换
PropertyEditor
ConversionService
BeanPostProcessor
FactoryBean
MetadataReader、ClassMetadata、 AnnotationMetadata
ExcludeFilter,IncludeFilter
有关spring的前置知识,可以观看我的上一篇文章spring底层架构源码剖析(二)
ApplicationContext
接上一篇文章,再将到BeanFactory后不得不提到ApplicationContext了,ApplicationContext着实是继承了BeanFactory的,但是ApplicationContext提供了比BeanFactory更多的功能,此中ApplicationContext两个比力告急的实现类:
1. AnnotationConfigApplicationContext
2. ClassPathXmlApplicationContext
AnnotationConfigApplicationContext
在idea的继承图如下,可以发现AnnotationConfigApplicationContext实现了许多的接口
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接口,拥有了以上全部的功能
ClassPathXmlApplicationContext
同样,在idea的继承图如下,可以发现ClassPathXmlApplicationContext实现了许多的接口
范例转换
在spring的源码中有许多范例转换的工具类,比方:PropertyEditor,ConversionService,TypeConverter等,他们可以将我们写的String转换为spring必要加载的类对象
PropertyEditor
- 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);
- }
- }
复制代码 怎样向Spring中注册PropertyEditor:
- @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;
- }
复制代码 ConversionService
ConversionService是比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<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;
- }
- }
复制代码 怎样向Spring中注册ConversionService:
- @Bean
- public ConversionServiceFactoryBean conversionService() {
- ConversionServiceFactoryBean conversionServiceFactoryBean = new
- ConversionServiceFactoryBean();
- conversionServiceFactoryBean.setConverters(Collections.singleton(new
- StringToUserConverter()));
- return conversionServiceFactoryBean;
- }
复制代码 BeanPostProcessor
BeanPostProcess表现Bena的后置处置惩罚器,我们可以界说一个或多个BeanPostProcessor,好比通 过以下代码界说一个BeanPostProcessor:
- @Component
- public class LcyyBeanPostProcessor implements BeanPostProcessor {
- @Override
- public Object postProcessBeforeInitialization(Object bean, String beanName) throws
- BeansException {
- if ("userService".equals(beanName)) {
- System.out.println("Bean的初始化前");
- }
- return bean;
- }
- @Override
- public Object postProcessAfterInitialization(Object bean, String beanName) throws
- BeansException {
- if ("userService".equals(beanName)) {
- System.out.println("Bean的初始化后");
- }
- return bean;
- }
- }
复制代码 一个BeanPostProcessor可以在恣意一个Bean的初始化之前以及初始化之后去额外的做一些用户自 界说的逻辑,固然,我们可以通过判断beanName来举行针对性处置惩罚(针对某个Bean,或某部门 Bean)。 因此可以通过界说BeanPostProcessor来干涉Spring创建Bean的过程。
FactoryBean
FactoryBean 着实是一个比力特殊的Bean,可以通过BeanPostPorcessor来干涉Spring创建Bean的过程,但是如果我们想一个 Bean完完全全由我们来创造,也是可以的,好比通FactoryBean
- @Component
- public class LcyyFactoryBean implements FactoryBean {
- @Override
- public Object getObject() throws Exception {
- UserService userService = new UserService();
- return userService;
- }
- @Override
- public Class<?> getObjectType() {
- return UserService.class;
- }
- }
复制代码 通过上面这段代码,我们本身创造了一个UserService对象,而且它将成为Bean。但是通过这种方式 创造出来的UserService的Bean,只会颠末初始化后,其他Spring的生命周期步调是不会颠末的,好比依赖注入。
MetadataReader、ClassMetadata、 AnnotationMetadata
在Spring中必要去剖析类的信息,好比类名、类中的方法、类上的注解,这些都可以称之为类的元数 据,以是Spring中对类的元数据做了抽象,并提供了一些工具类。MetadataReader表现类的元数据读取器,默认实现类为SimpleMetadataReader
- public class Test {
- public static void main(String[] args) throws IOException {
- SimpleMetadataReaderFactory simpleMetadataReaderFactory = new
- SimpleMetadataReaderFactory();
-
- // 构造一个MetadataReader
- MetadataReader metadataReader = simpleMetadataReaderFactory.getMetadataReader("com.lcyy.service.UserService");
-
- // 得到一个ClassMetadata,并获取了类名
- ClassMetadata classMetadata = metadataReader.getClassMetadata();
-
- System.out.println(classMetadata.getClassName());
-
- // 获取一个AnnotationMetadata,并获取类上的注解信息
- AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
- for (String annotationType : annotationMetadata.getAnnotationTypes()) {
- System.out.println(annotationType);
- }
- }
- }
复制代码 ExcludeFilter,IncludeFilter
这两个Filter是Spring扫描过程中用来过滤的。ExcludeFilter表现扫除过滤器,IncludeFilter表现包 含过滤器。 好比以下设置,表现扫描com.lcyy这个包下面的全部类,但是扫除UserService类,也就是就算它上面有@Component注解也不会成为Bean。
- @ComponentScan(value = "com.lcyy",
- excludeFilters = {@ComponentScan.Filter(
- type = FilterType.ASSIGNABLE_TYPE,
- classes = UserService.class)}.)
- public class AppConfig {
- }
复制代码 再好比以下设置,就算UserService类上没有@Component注解,它也会被扫描成为一个Bean。
- @ComponentScan(value = "com.lcyy",
- includeFilters = {@ComponentScan.Filter(
- type = FilterType.ASSIGNABLE_TYPE,
- classes = UserService.class)})
- public class AppConfig {
- }
复制代码 FilterType分为:
1. ANNOTATION:表现是否包罗某个注解
2. ASSIGNABLE_TYPE:表现是否是某个类
3. ASPECTJ:表现否是符合某个Aspectj表达式
4. REGEX:表现是否符合某个正则表达式
5. CUSTOM:自界说
在Spring的扫描逻辑中,默认会添加一个AnnotationTypeFilter给includeFilters,表现默认环境下 Spring扫描过程中会以为类上有@Component注解的就是Bean。
|