Spring Bean基础

Spring Bean 基础

定义 Spring Bean

什么是 BeanDefinition?

BeanDefinition 是Spring Framework 中定义 Bean 的配置元信息接口,包含:

  • Bean 类名;
  • Bean 的行为元素,如作用域、自动绑定模式,生命周期回调等;
  • 配置信息,比如 Bean 属性(Properties)
BeanDefinition 元信息
  • Class :Bean 全类名,必须是具体类,不能用抽象或接口;
  • Name:Bean 的名称或者 ID;
  • Scope:Bean 的作用域,如:singleton,prototype
  • Construstor arguments:Bean 构造器参数(用于依赖注入)
  • Properties:Bean 属性设置,用来依赖注入
  • Autowiring mode:Bean 自动绑定模式,如通过名称 byName
  • Lazy initialization mode:Bean 延迟初始化模式(延迟和非延迟)
  • Initialzation method:Bean 初始化回调方法名称
  • Destruction method:Bean 销毁回调方法名称

如何构建 BeanDefinition

  • 通过 BeanDefinitionBuilder
  • 通过 AbstractBeanDefinition 以及派生类
public class BeanDefinitionCreation {
    public static void main(String[] args) {
        //1.通过 BeanDefinitionBuilder 构建
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
        //通过属性设置
        builder.addPropertyValue("id",1);
        builder.addPropertyValue("name","白杨");
        //获取实例
        AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
        //2.通过 AbstractionBeanDefinition 以及派生类
        GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
        //设置 Bean 类型
        genericBeanDefinition.setBeanClass(User.class);
        //通过 MutablePropertyValues 批量操作属性
        MutablePropertyValues propertyValues = new MutablePropertyValues();
        propertyValues.addPropertyValue("id",2);
        propertyValues.addPropertyValue("name","baiyang");
        propertyValues.add("id",3).add("name","xiaobaiyang");
        //通过 set MutablePropertyValues 批量操作
        genericBeanDefinition.setPropertyValues(propertyValues);

    }
}
Spring Bean 命名
Bean 名称:

每个 Bean 拥有一个或多个标识符,这些标识符在 Bean 所在的容器必须是唯一的,通常一个 Bean 仅有一个标识符,如果需要额外的,可以考虑使用别名 Alias 扩充。

在基于 XML 配置元信息时,开发人员可以用 id 或 name 属性来规定 Bean 的标识符,通常 Bean 的标识符由字母组成,允许出现特殊字符。如果想要引入 Bean 的别名话,可以 name 属性使用逗号和分号来分割。

但 Bean 的 id 和 name 属性 并非定制的,如果留空的话,容器会为 Bean 自动生成唯一名称,Bean 的命名尽管没有限制,不过官方采用驼峰命名方式更符合 Java 命名规范。

Bean 默认生成名字的方式是通过 BeanNameGenerator 实现的。

Bean名称生成器(BeanNameGenerator)

有 Spring Framework 2.0.3 引入,框架内有两种实现:

  • DefaultBeanNameGenerator:默认通过 BeanNameGenerator 实现;
  • AnnotationBeanNameGenerator:基于注解扫描的 BeanNameGenerator 实现。
Bean 别名的价值和注册 Bean
  • 复用现有的 BeanDefinition
  • 更具有场景化的命名方法,比如:

<alias name="myApp-dataSource" alias="subsystemA-dataSource"/> <alias name="myApp-dataSource" alias="subsystemB-dataSource"/>

@Import(AnnotationBeanDefinitionDemo.Config.class)   //通过 Import 进行导入
public class AnnotationBeanDefinitionDemo {
    public static void main(String[] args) {
        //创建 BeanFactory 容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        //注册 配置类
        applicationContext.register(Config.class);

        //通过 BeanDefinition 注册 Api
        registerUserBeanDefinition(applicationContext,"xiao-baiyang");
        registerUserBeanDefinition(applicationContext);
        //启动 Spring 上下文
        applicationContext.refresh();
        Map<String, Config> configType = applicationContext.getBeansOfType(Config.class);
        Map<String, User> userType = applicationContext.getBeansOfType(User.class);

        System.out.println("Config 所有 Bean 的实例" + configType);
        System.out.println("User 所有 Bean 的实例" + userType);
        //1.通过 @Bean 方式定义
        //2.通过 @Component 方式
        //3.通过 @Import 导入
        //显示关闭 Spring 应用上下文
        applicationContext.close();
    }

    /**
     * 命名 Bean 的注册方式
     * @param registry
     * @param beanName
     */
    public static void registerUserBeanDefinition(BeanDefinitionRegistry registry ,String beanName){
        BeanDefinitionBuilder builder = genericBeanDefinition(User.class);
        builder.addPropertyValue("id",1L);
        builder.addPropertyValue("name","白杨");
        //判断 beanName 是否存在
        if (StringUtils.hasText(beanName)) {
            //注册 BeanDefinition
            registry.registerBeanDefinition(beanName,builder.getBeanDefinition());
        }else {
            BeanDefinitionReaderUtils.registerWithGeneratedName(builder.getBeanDefinition(),registry);
        }

    }
    public static void registerUserBeanDefinition(BeanDefinitionRegistry registry) {
        registerUserBeanDefinition(registry,null);
    }

    @Component   //定义当前类作为 Spring Bean (组件)
    public static class Config {
        //通过 Java 注解方式,定义一个 Bean
        @Bean(name = {"user","bai-yang"})
        public User user() {
            User user = new User();
            user.setId(2L);
            user.setName("baiyang");
            return user;
        }
    }
}
实例化和初始化 Spring Bean

常规方式:

  • 通过构造器
  • 通过静态工厂方法
  • 通过 Bean 工厂方法
  • 通过 FactoryBean

Bean初始化:

  • 基于 PostConstruct 标注方法

  • 实现 InitializingBean 接口的 afterPropertiesSet()

  • 自定义初始化方法

    XML 配置:<bean init-method = "init"/>

    Java 注解:@Bean(initMethod = “init”)

    Java API:AbstractBeanDefinition#setInitMethodName(String)

延迟初始化加载 Spring Bean

Bean 延迟初始化:

  • XML 配置:<bean lazy-init:“true”/>
  • Java 注解 @Lazy(true)
销毁 Spring Bean
  • @PreDestory 标注方法
  • 实现 DisposableBean 接口的 destory() 方法
  • 自定义销毁方法
    • XML 配置:<bean destory = "destory"/>
    • Java 注解:@Bean(destory = “destory”)
    • Java API:API:AbstractBeanDefinition#setDestroyMethodName(String)
垃圾回收 Spring Bean
  • 关闭 Spring 容器应用上下文
  • 执行 GC
  • Spring Bean 覆盖的 finalize() 方法被回调
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值