使用注解注册Bean的四种方法

刚开始学的时候,都是在xml里面注册类,或者直接在类上面写@Bean相关的注解。但是理解这些还不够,因为这些注册组件的效率并不高,此外,SpringBoot的源码往往并不是用上面的方法注册的,理解下面的注册方法有利于理解springboot。

@Import是关键的注解,可以直接引入类、配置类、注册类等。以下的组件注册和@Import有很大的关系。在进行下面的练习前,需要自行添加一些实体类。

1. @Import直接引入需要组装的类

@Import指定要注入Apple和Banana实体类

@EnableFruit 注解代码如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import({Apple.class, Banana.class})
public @interface EnableFruit {
}

然后在启动类里添加这个注解:

@SpringBootApplication
@EnableFood
public class EnableAnnotationTestApplication {

    public static void main(String[] args) {
        SpringApplication.run(EnableAnnotationTestApplication.class, args);
    }

}

测试代码:

@Autowired
Apple apple;

@Autowired
Banana banana;

@Test
void fruitTest() {
    System.out.println("apple = " + apple);
    System.out.println("banana = " + banana);
}

2. @Import引入配置类

@Import指定要注入一个配置类。我这里指定了自己创建的配置类ToolConfig类。

@EnableTool 注解如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import({ToolConfig.class})
public @interface EnableTool {
}

ToolConfig是个配置类,配置类的写法如下:

@Configuration
public class ToolConfig {
    @Bean
    public Pen pen() {
        return new Pen();
    }

    @Bean
    public Eraser eraser() {
        return new Eraser();
    }
}

测试代码:

@Autowired
Pen pen;

@Autowired
Eraser eraser;

@Test
void toolTest() {
    System.out.println("pen = " + pen);
    System.out.println("eraser = " + eraser);
}

3. @Import引入ImportSelector子类

@Import引入ImportSelector子类也可成功组装组件。

@EnableAnimal 注解代码如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import({AnimalImportSelector.class})
public @interface EnableAnimal {
}

AnimalImportSelector类代码如下:

public class AnimalImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{Tiger.class.getName(), Monkey.class.getName()};
    }
}

可以看到选择导入了Tiger和Monkey类进行组装。

同时,在启动类需要添加@EnableAnimal注解。

@SpringBootApplication
@EnableFruit
@EnableAnimal
public class EnableAnnotationTestApplication {

    public static void main(String[] args) {
        SpringApplication.run(EnableAnnotationTestApplication.class, args);
    }

}

测试:

@Autowired
Tiger tiger;

@Autowired
Monkey monkey;

@Test
void animalTest() {
    System.out.println("tiger = " + tiger);
    System.out.println("monkey = " + monkey);
}

3. @Import引入ImportBeanDefinitionRegistrar子类

这是用来定义Bean的类,同时也可以通过@Import引入。

@EnableFood 注解代码如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import({FoodImportDefinitionRegistrar.class})
public @interface EnableFood {
}

自己创建了一个子类,registerBeanDefinitions,代码如下,可以看到注册了两个bean。

public class FoodImportDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        registry.registerBeanDefinition("chicken", new RootBeanDefinition(Chicken.class));
        registry.registerBeanDefinition("pizza", new RootBeanDefinition(Pizza.class));
    }
}

同时,仍然需要在启动类上添加注解。

@SpringBootApplication
@EnableFruit
@EnableAnimal
@EnableFood
public class EnableAnnotationTestApplication {

    public static void main(String[] args) {
        SpringApplication.run(EnableAnnotationTestApplication.class, args);
    }

}

测试:

@Autowired
Chicken chicken;

@Autowired
Pizza pizza;

@Test
void foodTest() {
    System.out.println("chicken = " + chicken);
    System.out.println("pizza = " + pizza);
}

@Test
void contextLoads() {
}

以上为四种通过注解注册Bean的方法。后两种IDEA无法识别到bean而报错,但不会影响测试的运行。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值