Spring依赖查找

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\n", 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\n", 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...");
        }
    }
}
posted @ 2020-10-10 16:50  fly_bk  阅读(436)  评论(0编辑  收藏  举报