每天五分钟,学透Spring《一、Spring中是如何获取Bean》

576 阅读3分钟

图片

做一个单纯的程序汪,分享干货,聊聊人生。

微信公众号:后端架构进阶

关注我发现更多的干货,微服务、Spring源码、JVM、SpringCloud Alibaba、K8S等。

如果你觉得本文对你有帮助,麻烦给我点个赞,感谢支持!

在我们平时开发的过程中,使用一个Bean更多的是交给Spring的容器去管理,然后在需要的地方直接@Resource或者@Autowied就可以直接拿到我们的Bean。那么这个过程是怎么样的呢?

image.png

一、Spring容器中获取Bean

我们要从容器中获取Bean,怎么实现呢?Spring提供了两个类:

ClassPathXmlApplicationContext 基于xml文件

AnnotationConfigApplicationContext 基于注解

Spring的命名还是很规范的。

ClassPathXmlApplicationContext :从类路径下找到xml然后读取其中配置的Bean。比如在我的resources下定义了这个xml文件:

image.png

我的配置文件中的内容如下所示:

image.png

/**
 * bean的创建
 *
 * @author AerCool Yang
 * @date 2021-12-04 11:44:14
 */
public class Main {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("spring.xml");

        Object userService = context.getBean("userService");
        System.out.println(userService);
    }
}

运行结果如下:

我是UserService的构造方法。。。
com.aercool.bean.UserService@2925bf5b

这也是之前用的比较多的方式,不过目前更多使用的是基于注解的方式。

注解就很简单直观了。具体如下:

/**
 * 基于注解
 *
 * @author AerCool Yang
 * @date 2021-12-04 11:47:09
 */
public class Config {

    @Bean
    public UserService userService() {
        return new UserService();
    }
}

这里注意下就是我们并没有加上@configuration的注解。小伙伴们可以考虑下加和不加的区别,后面我们也会进行解释。

/**
 * Bean的创建
 *
 * @author AerCool Yang
 * @date 2021-12-04 11:44:14
 */
public class Main {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context =
            new AnnotationConfigApplicationContext(Config.class);
        Object userService = context.getBean("userService");

        System.out.println(userService);
    }
}

输出结果如下:

我是UserService的构造方法。。。
com.aercool.bean.UserService@618b19ad

二、加了@ComponentScan和不加的区别

从上面的代码我们可以知道,首先会去拿到Config.class这个对象,如果这个类上没加@ComponentScan注解,那么就只会去找到该对象下的@Bean注解的类,然后进行实例化。即使我加了一个OrderService,并且标注为@Service也读取不到的。

image.png

但是如果我把@ComponentScan加上效果就不一样了。是可以读取到的。这样就代表要去找到这个类的路径。然后到这个包下面扫描所有的标注了@component@service等等这样的注解的类,一并加入到我们的容器中。上面说的OrderService就可以被实例化了。

小伙伴们不信可以试试。

三、getBean都会做哪些事?

  • 如果加了扫描,遍历扫描路径
  • 将加了@Component@Service等注解的类加入到bean定义Map中 BeanDefinitionMap
  • Spring会根据规则生成Bean对应的beanName以及生成Bean,然后存入到我们一级缓存中,然后后面使用的时候就直接可以从缓存中拿了。
  • getBean()如果发现已经创建好了,直接会去从缓存中直接拿。

这就是获取一个Bean的过程。

好了,今天的文章就分享到这里。更多关于Spring的文章正在加班加点的写。喜欢的老铁,记得给个赞!

历史文章汇总

总结

以上就是之前的内容的总结和分享,感谢各位大佬的 关注点赞收藏

微信公众号:后端架构进阶

更多文章正在赶来,喜欢记得给我点个 👍 ,感谢支持!

公众号文章同步更新!关注我,不迷路!