spring-bean-definition

BeanDefinition的构建

beanDefinition的构建通常有两种方式,一种是builder的方式,另一种可以通过AbstractBeanDefinition的派生类进行手动构建。

方式一:

//方式一 通过 BeanDefinitionBuilder
AbstractBeanDefinition beanDef = BeanDefinitionBuilder.genericBeanDefinition(Cat.class)
		.addPropertyValue("name", "tom")
		.addPropertyValue("age", 2)
		.addPropertyValue("weight", 3.3)
		.getBeanDefinition();

方式二:

//方式二 通过 AbstractBeanDefinition 以及派生类
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(Cat.class);
//k-v
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.addPropertyValue(new PropertyValue("name", "tom1"));
pvs.addPropertyValue("age", 3);
pvs.add("weight", 4.1);
//set
beanDefinition.setPropertyValues(pvs);

BeanDefinition 注册

BeanDefinition的注册提供了多种方式,可以根据项目需要或个人偏好进行选择,但是整体上要么全部采用xml形式,或者全部采用java注解的形式,避免两种混用,增加开发维护成本。

  • XML 配置元信息
    • <bean name="xxx" .../>
  • java 注解配置元信息
    • @Component(及其派生注解)
    • 配置类的@Bean
    • @Import外部依赖导入形式
  • java API配置元信息
    • 命名方式:BeanDefinitionRegistry#registerBeanDefinition(String, BeanDefinition)
    • 非命名方式:BeanDefinitionReaderUtils.registerWithGeneratedName(AbstractBeanDefinition, BeanDefinitionRegistry)
    • 配置类方式(扫描):AnnotatedBeanDefinitionReader#register(Calss ...)

这里简单讨论几种方式

1.配置类中@Bean的方式,示例:

public class BeanDefConfig {
    @Bean
    public Cat cat() {
        return new Cat();
    }
}
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
//1.注册Configuration配置类
ctx.register(BeanDefConfig.class);
//启动上下文
ctx.refresh();
Map<String, Cat> beansOfType = ctx.getBeansOfType(Cat.class);
System.out.println(beansOfType);
ctx.close();

2.@Import外部依赖导入形式,示例:

@Import(BeanDefConfig.class)
public class BeanDefinitionRegisterDemo {
    public static void main(String[] args) {
        //2.注册配置类+@Import方式
        importMethod();
    }

    private static void importMethod() {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        //2.注册配置类+@Import方式
        ctx.register(BeanDefinitionRegisterDemo.class);
        //启动上下文
        ctx.refresh();
        Map<String, Cat> beansOfType = ctx.getBeansOfType(Cat.class);
        System.out.println(beansOfType);
        ctx.close();
    }
}

@Import是构建SpringBoot Starter的一种实现方式,实现功能组件化。

3.java API方式

@Import(BeanDefConfig.class)
public class BeanDefinitionRegisterDemo {
    public static void main(String[] args) {
        //register配置类
        //configClassRegister();
        //2.注册配置类+@Import方式
        //importMethod();
        //手动注册
        //manualRegisterDefine();
        scan();
    }

    private static void scan() {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(ctx);
        reader.register(BeanDefinitionRegisterDemo.class);
        ctx.refresh();
        Map<String, Cat> beansOfType = ctx.getBeansOfType(Cat.class);
        System.out.println("CAT: " + beansOfType);
        ctx.close();
    }

    private static void manualRegisterDefine() {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        //bean定义
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Cat.class)
                .addPropertyValue("name", "tom")
                .addPropertyValue("age", 3)
                .addPropertyValue("weight", 5.0)
                .getBeanDefinition();
        //1.指定名称
        ctx.registerBeanDefinition("cat01", beanDefinition);
        //2.自动生成名称
        BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, ctx);
        //启动上下文
        ctx.refresh();
        Map<String, Cat> beansOfType = ctx.getBeansOfType(Cat.class);
        System.out.println("CAT: " + beansOfType);
        ctx.close();
    }
}

 

此处给出在未指定beanName情况下使用默认的生成名称的方式源码如下:

	public static String uniqueBeanName(String beanName, BeanDefinitionRegistry registry) {
		String id = beanName;
		int counter = -1;

		// Increase counter until the id is unique.
		while (counter == -1 || registry.containsBeanDefinition(id)) {
			counter++;
			id = beanName + GENERATED_BEAN_NAME_SEPARATOR + counter;
		}
		return id;
	}

得到的beanName类似于:com.xx.xxx.Cat#0,若有重复数字递增。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值