1.目录
4.ApplicationContext 比 BeanFactory 多点啥
2.到底什么是 BeanFactory
-
它是 ApplicationContext 的父接口
-
它才是 Spring 的核心容器, 主要的 ApplicationContext 实现都【组合】了它的功能,【组合】是指 ApplicationContext 的一个重要成员变量就是 BeanFactory
-
下面附上一张类图
3.BeanFactory 能干点啥
-
它的成员变量 singletonObjects,内部包含了所有的单例 bean
-
实际上控制反转、基本的依赖注入、直至 Bean 的生命周期的各种功能,都由它的实现类提供
-
表面上只有 getBean
什么是singletonObjects呢?它一般被称位单例池。这里就不得不说一下有关于spring处理循环依赖的方法了:
spring处理 循环依赖主要是依靠三级缓存来实现:
- 一级缓存singletonObjects:单例池,用来缓存已经经过完整生命周期的bean。
- 二级缓存earlysingletonObjects ,用来缓存没有经历完整生命周期的bean。
- 三级缓存singtonFactory,用来缓存生成对象的factory。
spring在实例化bean'后需要进行依赖注入,如果需要被注入的bean不存在,就会去创建。比如:
- spring容器实例化了一个A对象,A对象需要注入B对象,
- 首先会查询缓存(看是否存在B对象),没有的话--->spring就会创建B对象,
- B对象却需要注入A对象,倘若只用1级缓存,由于A对象没有经历完整的生命周期,其不存在于一级缓存中,则会进入循环,再次创建A对象,又需要注入B.。
若采用2级缓存就可以解决普通对象的创建循环依赖问题,二级缓存中存在A对象,故B对象在创建时能够注入A对象,不会产生循环依赖。
3级缓存就涉及到了有关代理对象的循环引用问题。大家可以自行查阅资料。
4.ApplicationContext 比 BeanFactory 多点啥
-
ApplicationContext 组合并扩展了 BeanFactory 的功能
-
国际化、通配符方式获取一组 Resource 资源、整合 Environment 环境、事件发布与监听
国际化主要通过MessageSource来进行语言的转换。
5.@Value注解实现
-
ContextAnnotationAutowireCandidateResolver 作用之一,获取 @Value 的值
-
了解 ${ } 对应的解析器
-
了解 #{ } 对应的解析器
TypeConvert 的一项
private static void test3(AnnotationConfigApplicationContext context, ContextAnnotationAutowireCandidateResolver resolver, Field field) {
DependencyDescriptor dd1 = new DependencyDescriptor(field, false);
// 获取 @Value 的内容
String value = resolver.getSuggestedValue(dd1).toString();
System.out.println(value);
// 解析 ${}
value = context.getEnvironment().resolvePlaceholders(value);
System.out.println(value);
System.out.println(value.getClass());
// 解析 #{} @bean3
Object bean3 = context.getBeanFactory().getBeanExpressionResolver().evaluate(value, new BeanExpressionContext(context.getBeanFactory(), null));
// 类型转换
Object result = context.getBeanFactory().getTypeConverter().convertIfNecessary(bean3, dd1.getDependencyType());
System.out.println(result);
}
6.@Autoware原理
-
@Autowired 本质上是根据成员变量或方法参数的类型进行装配
-
如果待装配类型是 Optional,需要根据 Optional 泛型找到 bean,再封装为 Optional 对象装配
-
如果待装配的类型是 ObjectFactory,需要根据 ObjectFactory 泛型创建 ObjectFactory 对象装配
-
此方法可以延迟 bean 的获取
-
-
如果待装配的成员变量或方法参数上用 @Lazy 标注,会创建代理对象装配
-
此方法可以延迟真实 bean 的获取
-
被装配的代理不作为 bean
-
-
如果待装配类型是数组,需要获取数组元素类型,根据此类型找到多个 bean 进行装配
-
如果待装配类型是 Collection 或其子接口,需要获取 Collection 泛型,根据此类型找到多个 bean
-
如果待装配类型是 ApplicationContext 等特殊类型
-
会在 BeanFactory 的 resolvableDependencies 成员按类型查找装配
-
resolvableDependencies 是 map 集合,key 是特殊类型,value 是其对应对象
-
不能直接根据 key 进行查找,而是用 isAssignableFrom 逐一尝试右边类型是否可以被赋值给左边的 key 类型
-
-
如果待装配类型有泛型参数
-
需要利用 ContextAnnotationAutowireCandidateResolver 按泛型参数类型筛选
-
-
如果待装配类型有 @Qualifier
-
需要利用 ContextAnnotationAutowireCandidateResolver 按注解提供的 bean 名称筛选
-
-
有 @Primary 标注的 @Component 或 @Bean 的处理
-
与成员变量名或方法参数名同名 bean 的处理
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(A47_1.class);
DefaultListableBeanFactory beanFactory = context.getDefaultListableBeanFactory();
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
// 1. 根据成员变量的类型注入
DependencyDescriptor dd1 = new DependencyDescriptor(Bean1.class.getDeclaredField("bean2"), false);
System.out.println(beanFactory.doResolveDependency(dd1, "bean1", null, null));
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
// 2. 根据参数的类型注入
Method setBean2 = Bean1.class.getDeclaredMethod("setBean2", Bean2.class);
DependencyDescriptor dd2 = new DependencyDescriptor(new MethodParameter(setBean2, 0), false);
System.out.println(beanFactory.doResolveDependency(dd2, "bean1", null, null));
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
// 3. 结果包装为 Optional<Bean2>
DependencyDescriptor dd3 = new DependencyDescriptor(Bean1.class.getDeclaredField("bean3"), false);
if (dd3.getDependencyType() == Optional.class) {
dd3.increaseNestingLevel();
Object result = beanFactory.doResolveDependency(dd3, "bean1", null, null);
System.out.println(Optional.ofNullable(result));
}
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
// 4. 结果包装为 ObjectProvider,ObjectFactory
DependencyDescriptor dd4 = new DependencyDescriptor(Bean1.class.getDeclaredField("bean4"), false);
if (dd4.getDependencyType() == ObjectFactory.class) {
dd4.increaseNestingLevel();
ObjectFactory objectFactory = new ObjectFactory() {
@Override
public Object getObject() throws BeansException {
return beanFactory.doResolveDependency(dd4, "bean1", null, null);
}
};
System.out.println(objectFactory.getObject());
}
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
// 5. 对 @Lazy 的处理
DependencyDescriptor dd5 = new DependencyDescriptor(Bean1.class.getDeclaredField("bean2"), false);
ContextAnnotationAutowireCandidateResolver resolver = new ContextAnnotationAutowireCandidateResolver();
resolver.setBeanFactory(beanFactory);
Object proxy = resolver.getLazyResolutionProxyIfNecessary(dd5, "bean1");
System.out.println(proxy);
System.out.println(proxy.getClass());
}
static class Bean1 {
@Autowired @Lazy private Bean2 bean2;
@Autowired public void setBean2(Bean2 bean2) {
this.bean2 = bean2;
}
@Autowired private Optional<Bean2> bean3;
@Autowired private ObjectFactory<Bean2> bean4;
}