【Spring学习-2-1】底层架构核心概念-BeanDefinition

一、BeanDefinition含义(理解描述)

BeanDefinition表示Spring容器中Bean的定义,在BeanDefinition类中存在很多属性用来描述一个Bean的定义。
注释:Spring容器中Bean的定义,就是通过xml配置、扫描注解把需要纳入到Spring容器中的类,通过BeanDefinition来定义。

二、BeanDefinition类中属性:

beanClass,表示Bean类型
scope,表示Bean作用域,单例或原型等
lazyInit:表示Bean是否是懒加载
initMethodName:表示Bean初始化时要执行的方法
destroyMethodName:表示Bean销毁时要执行的方法
等等...

基于以上内容,我们可以理解为BeanDefinition对象就是一个Bean的元数据,为什么Bean的元数据需要一个BeanDefinition来存储元数据呢?
因为一个被Spring容器管理的Bean不仅仅是放到Spring容器中,而是要应对不同场景,比如有单例和多例的Bean,有的Bean需要懒加载,有的Bean在被注入的时候需要执行初始化方法等等,而这些都需要额外来记录,单单靠Bean对象所对应的类自己是不行的,Bean对象所对应的类也就是Java类,他是相对于Spring更底层的东西,属于Jvm层,而Bean是属于Spring体系,Spring体系就需要想办法来记录这个Bean的信息,所以需要BeanDefinition对象保存Bean的元数据。

三、定义Bean的方式

3.1 声明式定义Bean

xml配置【<bean/>】
方法注解【@Bean】
类上注解【@Component(@Service,@Controller)】

3.2 编程式定义Bean

基础代码:

Config.java

package cn.edkso.coreConcept;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("cn.edkso.coreConcept")
public class Config {
}

TestService.java

package cn.edkso.coreConcept;

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;

//@Component
//@Controller
@Service
public class TestService {

    public TestService() {
        System.out.println("TestService被创建了!");
    }

    public void init(){
        System.out.println("TestService执行初始化方法!");
    }
}

编程式定义Bean代码:

    /**
     * 编程式定义BeanDefinition
     */
    private static void test1(){

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);

        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        beanDefinition.setBeanClass(TestService.class);
        beanDefinition.setScope("prototype");
//        beanDefinition.setScope("singleton");
        beanDefinition.setLazyInit(false);
        beanDefinition.setInitMethodName("init");

        context.registerBeanDefinition("testService", beanDefinition);

        System.out.println(context.getBean("testService"));
        System.out.println(context.getBean("testService"));
    }

注释:编程式方式定义的Bean方式和声明式方式所定义的Bean,最终都会被Spring解析为对应的BeanDefinition对象,并放入Spring容器中。

四、BeanDefinition读取器

在Spring源码中提供了几种BeanDefinition读取器 (BeanDefinitionReader),这些BeanDefinitionReader在我们使用Spring时用得少,但在Spring 源码中用得多,相当于Spring源码的基础设施。

4.1 AnnotatedBeanDefinitionReader

AnnotatedBeanDefinitionReader Bean读取器
– 1.通过该Bean读取器,可以把一个类直接读取成BeanDefinition并进行注册;
在读取过程中,会检测指定类中的各种注解,并根据注解做相应的处理。
– 3.new AnnotationConfigApplicationContext(Config.class)
内部源码就是通过AnnotatedBeanDefinitionReader读取的Config配置类

    /**
     * AnnotatedBeanDefinitionReader   Bean读取器
     * -- 1.通过该Bean读取器,可以把一个类直接读取成BeanDefinition并进行注册;
     *      在读取过程中,会检测指定类中的各种注解,并根据注解做相应的处理。
     * -- 3.new AnnotationConfigApplicationContext(Config.class)
     *      内部源码就是通过AnnotatedBeanDefinitionReader读取的Config配置类
     */
    private static void test2(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);

        AnnotatedBeanDefinitionReader abd = new AnnotatedBeanDefinitionReader(context);
        abd.register(TestService.class);

        System.out.println(context.getBean("testService"));
    }

4.2 XmlBeanDefinitionReader

xml配置Bean文件:
spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="testService" class="cn.edkso.coreConcept.TestService"></bean>

</beans>

XmlBeanDefinitionReader Bean读取器:

XmlBeanDefinitionReader Bean读取器
– 1.在xml文件中配置的bean可以通过此读取器读取,并进行注册。
– 2.在早期Spring版本中,大多数都是通过xml来配置Bean,这样做的缺点是配置文件太多,并且耦合度高

    /**
     * XmlBeanDefinitionReader  Bean读取器
     * -- 1.在xml文件中配置的bean可以通过此读取器读取,并进行注册。
     * -- 2.在早期Spring版本中,大多数都是通过xml来配置Bean,这样做的缺点是配置文件太多,并且耦合度高
     */
    private static void test3(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);

        XmlBeanDefinitionReader xbd = new XmlBeanDefinitionReader(context);
        xbd.loadBeanDefinitions("spring.xml");

        System.out.println(context.getBean("testService"));
    }

4.3 ClassPathBeanDefinitionScanner

ClassPathBeanDefinitionScanner Bean读取器(扫描器)
– 1.扫描Bean读取器,会扫描指定包路径下的Bean进行读取,并进行注册。
– 2.在指定包下,配置@Service、@Component、@Controller 等注解的才是要纳入Spring进行管理的Bean

    /**
     * ClassPathBeanDefinitionScanner  Bean读取器(扫描器)
     * -- 1.扫描Bean读取器,会扫描指定包路径下的Bean进行读取,并进行注册。
     * -- 2.在指定包下,配置@Service、@Component、@Controller 等注解的才是要纳入Spring进行管理的Bean
     */
    private static void test4(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);

        ClassPathBeanDefinitionScanner cpbd = new ClassPathBeanDefinitionScanner(context);
        cpbd.scan("cn.edkso.coreConcept");

        System.out.println(context.getBean("testService"));
    }

版权声明:
作者:十下
链接:https://blog.edkso.cn/?p=1027
来源:十下博客
文章版权归作者所有,未经允许请勿转载。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值