栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring容器加入bean的几种方式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring容器加入bean的几种方式

文章目录
  • 一、五种方式简介
  • 二、五种方式具体介绍
    • 1、@Configuration + @Bean
    • 2、@Componet + @ComponentScan
    • 3、@import注解导入
      • 1、import直接导入类
      • 2、@import + importSelector
      • 3、@import + importBeanDefinitionRegistrar
      • 4、@import + DeferredimportSelector
    • 4、使用FactoryBean接口
    • 5、使用 BeanDefinitionRegistryPostProcessor

一、五种方式简介
  • @Configuration + @Bean
  • @ComponentScan + @Component
  • @import 配合接口进行导入
  • 使用FactoryBean。
  • 实现BeanDefinitionRegistryPostProcessor进行后置处理。
二、五种方式具体介绍 1、@Configuration + @Bean

@Configuration用来声明一个配置类,然后使用 @Bean 注解,用于声明一个bean,将其加入到Spring容器中。这种方式是我们最常用的一种

@Configuration
public class MyConfiguration {
    @Bean
    public Person person() {
        Person person = new Person();
        person.setName("spring");
        return person;
    }
}
2、@Componet + @ComponentScan

@Componet中文译为组件,放在类名上面,然后@ComponentScan放置在我们的配置类上,然后可以指定一个路径,进行扫描带有@Componet注解的bean,然后加至容器中。这种方式也较为常用,spring扫描包路径就是使用这种方式,这样可以一下子扫描很多个bean到容器

// 该类在com.shawn.*包下面
@Component
public class Person {
    private String name;
 
    public String getName() {
 
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + ''' +
                '}';
    }
}
 
 /
    Class[] value();
 
}
1、import直接导入类

直接使用@import导入了一个类,然后自动的就被放置在IOC容器中了。注意我们的Person类上 就不需要任何的注解了,直接导入即可

public class Person {
    private String name;
 
    public String getName() {
 
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + ''' +
                '}';
    }
}

@import(Person.class)
public class Demo {
 
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo.class);
        Person bean = applicationContext.getBean(Person.class);
        System.out.println(bean);
    }
}
 
2、@import + importSelector

自定义了一个MyimportSelector 实现了 importSelector 接口,重写selectimports方法,然后将我们要导入的类的全限定名写在里面即可导入

@import(MyimportSelector.class)
public class Demo {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo.class);
        Person bean = applicationContext.getBean(Person.class);
        System.out.println(bean);
    }
}

class MyimportSelector implements importSelector {
    @Override
    public String[] selectimports(Annotationmetadata importingClassmetadata) {
        //这里需要具体到类名
        return new String[]{"com.shawn.Person"};
    }
}
3、@import + importBeanDefinitionRegistrar

这种方式需要实现 importBeanDefinitionRegistrar 接口中的方法。BeanDefinition可以简单理解为bean的定义(bean的元数据),也是需要放在IOC容器中进行管理的,先有bean的元数据,applicationContext再根据bean的元数据去创建Bean。

@import(MyimportBeanDefinitionRegistrar.class)
public class Demo {
 
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo.class);
        Person bean = applicationContext.getBean(Person.class);
        System.out.println(bean);
    }
}
 
class MyimportBeanDefinitionRegistrar implements importBeanDefinitionRegistrar {
 
    @Override
    public void registerBeanDefinitions(Annotationmetadata importingClassmetadata, BeanDefinitionRegistry registry) {
        // 构建一个beanDefinition
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Person.class).getBeanDefinition();
        // 将beanDefinition注册到Ioc容器中
        registry.registerBeanDefinition("person", beanDefinition);
    }
}
4、@import + DeferredimportSelector

这种方式也需要我们进行实现接口,其实它和@import的第二种方式差不多,DeferredimportSelector 它是 importSelector 的子接口,所以实现的方法和第二种无异。只是Spring的处理方式不同,它和Spring Boot中的自动导入配置文件延迟导入有关,非常重要

@import(MyDeferredimportSelector.class)
public class Demo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo.class);
        Person bean = applicationContext.getBean(Person.class);
        System.out.println(bean);
    }
}
class MyDeferredimportSelector implements DeferredimportSelector {
    @Override
    public String[] selectimports(Annotationmetadata importingClassmetadata) {
        // 也是直接将Person的全限定名放进去
        return new String[]{Person.class.getName()};
    }
}

上述三类还可以搭配@Configuration注解使用,用于导入一个配置类

4、使用FactoryBean接口

FactoryBean接口和BeanFactory不一样,BeanFactory顾名思义 bean工厂,它是IOC容器的顶级接口。

下述代码通过@Configuration + @Bean的方式将 PersonFactoryBean 加入到容器中,注意,我没有向容器中注入 Person, 而是直接注入的 PersonFactoryBean 然后从容器中拿Person这个类型的bean,成功运行。

@Configuration
public class Demo {
    @Bean
    public PersonFactoryBean personFactoryBean() {
        return new PersonFactoryBean();
    }
 
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo.class);
        Person bean = applicationContext.getBean(Person.class);
        System.out.println(bean);
    }
}
 
class PersonFactoryBean implements FactoryBean {
 
    
    @Override
    public Person getObject() throws Exception {
        return new Person();
    }
    
    @Override
    public Class getObjectType() {
        return Person.class;
    }
}
5、使用 BeanDefinitionRegistryPostProcessor

这种方式也是利用到了 BeanDefinitionRegistry,在Spring容器启动的时候会执行 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 方法,大概意思就是等beanDefinition加载完毕之后,对beanDefinition进行后置处理,可以在此进行调整IOC容器中的beanDefinition,从而干扰到后面进行初始化bean。

下述代码中我们手动向beanDefinitionRegistry中注册了person的BeanDefinition,最终成功将person加入到applicationContext中

public class Demo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        MyBeanDefinitionRegistryPostProcessor beanDefinitionRegistryPostProcessor = new MyBeanDefinitionRegistryPostProcessor();
        applicationContext.addBeanFactoryPostProcessor(beanDefinitionRegistryPostProcessor);
        applicationContext.refresh();
        Person bean = applicationContext.getBean(Person.class);
        System.out.println(bean);
    }
}
 
class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
 
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Person.class).getBeanDefinition();
        registry.registerBeanDefinition("person", beanDefinition);
    }
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
 
    }
}
 

参考文章

https://blog.csdn.net/weixin_43741092/article/details/120176466

https://mp.weixin.qq.com/s/NpTNVGqU4dQwwgec3X4ibg

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/682548.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号