延迟依赖查找
Bean延迟依赖查找接口
- org.springframework.beans.factory.ObjectFactory
- org.springframework.beans.factory.ObjectProvider
- Spring 5对java 8特性扩展
- 函数式接口
- getIfAvailiable(Supplier)
- IfAvaliable(Consumer)
- Stream扩展-Stream()
依赖查找安全性对比
注意:层次性依赖查找的安全性取决于其扩展的单一或集合类型的BeanFactory接口
内建可查找的依赖
- 函数式接口
- Spring 5对java 8特性扩展
- AbstractApplicationContext内建可查找的依赖
注解驱动Spring应用上下文内建可查找的依赖(部分)
依赖查找中的经典异常 -
BeansException子类型
public class NoUniqueBeanDefinitionExceptionDemo {
public static void main(String[] args) {
//创建BeanFactory容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
//ObjectProviderDemo Class(配置类)
applicationContext.register(NoUniqueBeanDefinitionExceptionDemo.class);
//启动spring应用上下文
applicationContext.refresh();
try {
applicationContext.getBean(String.class);
} catch (NoUniqueBeanDefinitionException e){
System.err.printf("Spring 应用上下文存在 %d 个 s% 类型的 Bean ,具体原因:%s%n",
e.getNumberOfBeansFound(),
String.class.getName(),
e.getMessage());
}
//显示的关闭spring应用上下文
applicationContext.close();
}
@Bean
public String bean1(){
return "bean1";
}
@Bean
public String bean2(){
return "bean2";
}
}
public class BeanInstanationExceptionDemo {
public static void main(String[] args) {
//创建BeanFactory容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
//注册BeanDefinition Bean Class 是一个 CharSequence 接口
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(CharSequence.class);
applicationContext.registerBeanDefinition("errorBean",beanDefinitionBuilder.getBeanDefinition());
//启动spring应用上下文
applicationContext.refresh();
//显示的关闭spring应用上下文
applicationContext.close();
}
}
public class BeanCreationExceptionDemo {
public static void main(String[] args) {
//创建BeanFactory容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
//注册BeanDefinition Bean Class 是一个 POJO 普通类 ,不过初始化方法回调时抛出异常
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(POJO.class);
applicationContext.registerBeanDefinition("errorBean",beanDefinitionBuilder.getBeanDefinition());
//启动spring应用上下文
applicationContext.refresh();
//显示的关闭spring应用上下文
applicationContext.close();
}
static class POJO implements InitializingBean {
@PostConstruct // CommonAnnotationBeanProcessor
public void init() throws Throwable{
throw new Throwable("init() : For Purpose....");
}
public void afterPropertiesSet() throws Exception {
throw new Exception("For purposes.....");
}
}
}
面试题
ObjectBeanFactory 与 BeanFactory 的区别?
答:ObjectBeanFactory 与 BeanFactory均提供依赖查找的能力。不过,ObjectBeanFactory仅关注一个或一种类型的Bean的依赖查找,并且自身不具备依赖查找的能力,能力由BeanFactory输出。BeanFactory提供l单一类型、集合类型及层次性等多种依赖查找的方式。
BeanFactory.getBean方法的执行是线程安全的吗?
答:BeanFactory.getBean方法的执行是线程安全,操作过程中会添加互斥锁。