spring-core-3-22 | Spring IoC依赖查找:依赖注入还不够吗?依赖查找存在的价值几何?

Spring IoC 依赖查找

根据Bean 名称查找

实时查找

延迟查找

根据Bean 类型查找

单个Bean 对象

集合Bean 对象

根据Bean 名称+ 类型查找

根据Java 注解查找

单个Bean 对象

集合Bean 对象

代码示例

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.geekbang.thinking.in.spring.ioc.overview.dependency.lookup;

import org.geekbang.thinking.in.spring.ioc.overview.annotation.Super;
import org.geekbang.thinking.in.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Map;

/**
 * 22 | Spring IoC依赖查找:依赖注入还不够吗?依赖查找存在的价值几何?
 * 依赖查找示例, 具体的原理后面章节还会讲
 *
 * @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
 * @since
 */
public class DependencyLookupDemo {

    public static void main(String[] args) {
        // 配置 XML 配置文件
        // 启动 Spring 应用上下文
        // 配置文件在 dependency-lookup-context.xml
        // 这里作者建议, 配置文件最好放在元数据目录, 即 META-INF
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-lookup-context.xml");
        // 22-1.1 根据bean的名称查找, 实时查找
        lookupInRealTime(beanFactory);
        // 22-1.2 根据bean的名称查找, 延迟查找
        lookupInLazy(beanFactory);
        // 22-2.1 根据Bean类型查找, 单个Bean对象
        lookupByType(beanFactory);
        // 22-2.2 根据Bean类型查找, 集合Bean对象
        lookupCollectionByType(beanFactory);
        // 22-2.3 根据Bean 名称+ 类型查找, 不做演示,
        // 就是调用getBean(String name, Class<T> requiredType)
        // 22-4. 根据Java 注解查找对象
        lookupByAnnotationType(beanFactory);

//        lookupInRealTime(beanFactory);
//        lookupInLazy(beanFactory);
    }

    /**
     * 22-4. 根据Java 注解查找
     * @param beanFactory
     */
    private static void lookupByAnnotationType(BeanFactory beanFactory) {
        if (beanFactory instanceof ListableBeanFactory) {
            ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
            // SuperUser 也需要在配置文件中注册
            // 这里需要配置一个primary, 否则会报错, 因为有两个类
            Map<String, User> users =
                    (Map) listableBeanFactory.getBeansWithAnnotation(Super.class);
            System.out.println("查找标注 @Super 所有的 User 集合对象:" + users);
        }
    }

    /**
     * 22-2. 根据Bean类型查找
     * 22-2.2 集合Bean对象
     * @param beanFactory
     */
    private static void lookupCollectionByType(BeanFactory beanFactory) {
        if (beanFactory instanceof ListableBeanFactory) {
            // 这里 ListableBeanFactory 接口后面会再讨论, 先用着
            ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
            // a Map with the matching beans, containing the bean names as keys
            // and the corresponding bean instances as values
            Map<String, User> users = listableBeanFactory.getBeansOfType(User.class);
            System.out.println("查找到的所有的 User 集合对象:" + users);
        }
    }

    /**
     * 22-2. 根据Bean类型查找
     * 22-2.1 单个Bean对象
     * @param beanFactory
     */
    private static void lookupByType(BeanFactory beanFactory) {
        User user = beanFactory.getBean(User.class);
        System.out.println("实时查找:" + user);
    }

    /**
     * 22-1. 根据bean的名称查找
     * 22-1.2 延迟查找
     * 注意这个和 spring里面一个延迟加载的Bean 是两回事,
     * 这里用到的 objectFactory 也要注册在配置文件内
     *
     * 延迟依赖查找主要用于获取 BeanFactory 后,不马上获取相关的 Bean,
     * 比如在 BeanFactoryPostProcessor 接口中获取 ConfigurableListableBeanFactory 时,
     * 不马上获取,降低 Bean 过早初始化的情况
     *
     * 这里有一个问题, ObjectFactory, FactoryBean 和 BeanFactory 三者区别是?
     * ObjectFactory 对象并不是直接返回了实际的 Bean,而是一个 Bean 的查找代理。
     * 当得到 ObjectFactory 对象时,相当于 Bean 没有被创建,
     * 只有当 getObject() 方法时,才会触发 Bean 实例化等生命周期
     *
     * FactoryBean 是一种特殊的 Bean,需要注册到 IoC 容器,
     * 通过容器 getBean 获取 FactoryBean#getObject() 方法的内容,
     *
     * BeanFactory#getBean 则是依赖查找,如果 Bean 没有初始化,那么将从底层查找或构建。
     * @param beanFactory
     */
    private static void lookupInLazy(BeanFactory beanFactory) {
        // spring3.0 之前不支持泛型强转, java5 有的泛型
        // 实际上ObjectFactory不会生成新的bean, 这是其与FactoryBean的一个重大区别
        ObjectFactory<User> objectFactory =
                (ObjectFactory<User>) beanFactory.getBean("objectFactory");
        User user = objectFactory.getObject();
        System.out.println("延迟查找:" + user);
    }

    /**
     *
     * 22-1. 根据bean的名称查找
     * 22-1.1 实时查找
     * 还记得最早使用xml文件, 使用id来注册bean的时光么?
     * User类注册在配置文件里了
     * @param beanFactory
     */
    private static void lookupInRealTime(BeanFactory beanFactory) {
        User user = (User) beanFactory.getBean("user");
        System.out.println("实时查找:" + user);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值