Spring依赖查找
延迟依赖查找
import com.fly.demo.User;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
/**
* 延迟依赖查找
* 通过 {@link org.springframework.beans.factory.ObjectProvider} 进行依赖查找
*/
public class ObjectProviderDemo {
public static void main(String... args) {
AnnotationConfigApplicationContext applicationContext
= new AnnotationConfigApplicationContext();
applicationContext.register(ObjectProviderDemo.class);
applicationContext.refresh();
ObjectProvider<String> objectProvider = applicationContext.getBeanProvider(String.class);
// 只会得到一个,如多个取 Primary 的
System.out.println(objectProvider.getObject());
objectProvider.stream().forEach(System.out::println);
ObjectProvider<User> userObjectProvider = applicationContext.getBeanProvider(User.class);
User user = userObjectProvider.getIfAvailable(() -> {
System.out.println("没找到!新建一个");
return new User();
});
System.out.println(user);
applicationContext.close();
}
@Bean
@Primary
public String message1() {
return "Message1";
}
@Bean
public String message2() {
return "Message2";
}
}
层次性依赖
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.HierarchicalBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* 层次性依赖查找示例
* {@link HierarchicalBeanFactory}
*/
public class HierarchicalDependencyLookupDemo {
public static void main(String... args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
// 设置 Parent BeanFactory
HierarchicalBeanFactory parentBeanFactory = createParentBeanFactory();
beanFactory.setParentBeanFactory(parentBeanFactory);
// displayContainsLocalBean(beanFactory, "user");
// displayContainsLocalBean(parentBeanFactory, "user");
displayContainsBean(beanFactory, "user");
displayContainsBean(parentBeanFactory, "user");
// 启动应用上下文
applicationContext.refresh();
// 关闭应用上下文
applicationContext.close();
}
private static void displayContainsBean(HierarchicalBeanFactory beanFactory, String beanName) {
System.out.printf("当前 BeanFactory[%s] 是否包含 Bean[name : %s] : %s
", beanFactory, beanName,
containsBean(beanFactory, beanName));
}
private static boolean containsBean(HierarchicalBeanFactory beanFactory, String beanName) {
BeanFactory parentBeanFactory = beanFactory.getParentBeanFactory();
if (parentBeanFactory instanceof HierarchicalBeanFactory) {
HierarchicalBeanFactory parentHierarchicalBeanFactory = HierarchicalBeanFactory.class.cast(parentBeanFactory);
if (containsBean(parentHierarchicalBeanFactory, beanName)) {
return true;
}
}
return beanFactory.containsLocalBean(beanName);
}
private static void displayContainsLocalBean(HierarchicalBeanFactory beanFactory, String beanName) {
System.out.printf("当前 BeanFactory[%s] 是否包含 Local Bean[name : %s] : %s
", beanFactory, beanName,
beanFactory.containsLocalBean(beanName));
}
private static ConfigurableListableBeanFactory createParentBeanFactory() {
// 创建 BeanFactory 容器
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
// XML 配置文件 ClassPath 路径
String location = "classpath:/META-INF/dependency-lookup-context.xml";
// 加载配置
reader.loadBeanDefinitions(location);
return beanFactory;
}
}
依赖查找中的经典异常
异常类型 |
触发条件(举例) |
场景举例 |
NoSuchBeanDefinitionException |
当查找 Bean 不存在于 IoC 容器时 |
BeanFactory#getBean ObjectFactory#getObject |
NoUniqueBeanDefinitionExceptio n |
类型依赖查找时,IoC 容器存在多 个 Bean 实例 |
BeanFactory#getBean(Cla ss) |
BeanInstantiationException |
当 Bean 所对应的类型非具体类时 |
BeanFactory#getBean |
BeanCreationException |
当 Bean 初始化过程中 |
Bean 初始化方法执行异常 时 |
BeanDefinitionStoreException |
当 BeanDefinition 配置元信息非法 时 |
XML 配置资源无法打开时 |
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import javax.annotation.PostConstruct;
/**
* BeanCreationException 初始化异常 示例
*/
public class BeanCreationExceptionDemo {
public static void main(String... args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 注册 BeanDefinition Bean Class 是一个 POJO 普通类,不过初始化方法回调时抛出异常
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(POJO.class);
applicationContext.registerBeanDefinition("errorBean", beanDefinitionBuilder.getBeanDefinition());
// 启动应用上下文
applicationContext.refresh();
// 关闭应用上下文
applicationContext.close();
}
static class POJO implements InitializingBean {
@PostConstruct // CommonAnnotationBeanPostProcessor
public void init() throws Exception {
throw new Exception("init() : For purposes...");
}
@Override
public void afterPropertiesSet() throws Exception {
throw new Exception("afterPropertiesSet() : For purposes...");
}
}
}