首页 > 其他分享 >将 Bean 放入 Spring 容器中的五种方式

将 Bean 放入 Spring 容器中的五种方式

时间:2022-10-16 17:04:11浏览次数:48  
标签:applicationContext String Spring bean public Person Bean 五种 class


文章目录

1.@Configuration + @Bean

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

2.@Componet + @ComponentScan

@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 + '\'' +
'}';
}
}

@ComponentScan(basePackages = "com.springboot.*")
public class Demo1 {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class);
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
}
}

3.@Import注解导入

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {

/**
* 用于导入一个class文件
* {@link Configuration @Configuration}, {@link ImportSelector},
* {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.
*/
Class<?>[] value();

}

3.1 @Import直接导入类

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类,然后尝试从applicationContext中取,成功拿到
**/
@Import(Person.class)
public class Demo1 {

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

3.2 @Import + ImportSelector

@Import(MyImportSelector.class)
public class Demo1 {

public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.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.springboot.pojo.Person"};
}
}

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

3.3 @Import + ImportBeanDefinitionRegistrar

@Import(MyImportBeanDefinitionRegistrar.class)
public class Demo1 {

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

class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 构建一个beanDefinition, 关于beanDefinition我后续会介绍,可以简单理解为bean的定义.
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Person.class).getBeanDefinition();
// 将beanDefinition注册到Ioc容器中.
registry.registerBeanDefinition("person", beanDefinition);
}
}

3.4 @Import + DeferredImportSelector

@Import(MyDeferredImportSelector.class)
public class Demo1 {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.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()};
}
}

DeferredImportSelector 它是 ImportSelector 的子接口, 它和Spring Boot中的自动导入配置文件 延迟导入有关.

4.使用FactoryBean接口

FactoryBean 是一个Bean, BeanFactory 为ioc 工厂

@Configuration
public class Demo1 {
@Bean
public PersonFactoryBean personFactoryBean() {
return new PersonFactoryBean();
}

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

class PersonFactoryBean implements FactoryBean<Person> {

/**
* 直接new出来Person进行返回.
*/
@Override
public Person getObject() throws Exception {
return new Person();
}
/**
* 指定返回bean的类型.
*/
@Override
public Class<?> getObjectType() {
return Person.class;
}
}

5.使用 BeanDefinitionRegistryPostProcessor

这种方式也是利用到了 ​​BeanDefinitionRegistry​​​, 在Spring容器启动的时候会执行 ​​BeanDefinitionRegistryPostProcessor​​​ 的 ​​postProcessBeanDefinitionRegistry​​ 方法。

等​​beanDefinition​​​加载完毕之后, 对 ​​beanDefinition​​​ 进行后置处理, 可以在此进行调整IOC容器中的​​beanDefinition​​​,从而干扰到后面进行初始化​​bean​​。

public class Demo1 {
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 {

}
}


标签:applicationContext,String,Spring,bean,public,Person,Bean,五种,class
From: https://blog.51cto.com/c959c/5760422

相关文章

  • Spring的FactoryBean
    Spring框架创建Javabean有三种方法无参构造方法静态工厂实例工厂Spring里面的FactoryBean是对实例工厂的优化和增强。本文展示Spring框架的FactoryBean接口的使用......
  • SpringBoot 扩展性接口
    1.可扩展的接口启动调用顺序图​​org.springframework.beans.factory.xxx​​​​org.springframework.boot.xxx​​​​org.springframework.context.xxx​​ApplicationC......
  • Springboot 服务停止后执行方法
    importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.beans.factory.DisposableBean;importorg.springframework.context.annotatio......
  • SpringBoot整合ES查询
    springboot整个es有很多钟方法,比如TransportClient、RestClient、RestHighLevelClient、SpringData-Es、Elasticsearch-SQL等。ElasticSearch官方提供了3个Client,具体......
  • Spring Cloud Nacos(一)
    PropertySourceLocator加载原理SpringApplication.run在springboot项目启动时,有一个prepareContext的方法,它会回调所有实现了ApplicationContextInitializer的实例,来做......
  • Spring boot JDBC
    引入包 yml配置      @Repository表求该类是持久层依赖注入的对象    queryForObject查询单一一条记录。query查询多条记录  服务后端......
  • SpringBean的生命周期
    SpringBean的生命周期SpringBean的生命周期大体如下:Instantiation:实例化bean(完成构造器注入)依赖注入:属性(接口)注入,setter注入aware:beanName,beanFactory,app......
  • 83-springboot 多模块打包成jar
    主项目:<packaging>pom</packaging>打包配置: <!--指定使用maven打包--> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <arti......
  • 一篇文章带你掌握主流办公框架——SpringBoot
    一篇文章带你掌握主流办公框架——SpringBoot在之前的文章中我们已经学习了SSM的全部内容以及相关整合SSM是Spring的产品,主要用来简化开发,但我们现在所介绍的这款框架—......
  • 结合springboot条件注入@ConditionalOnProperty以及@ConfigurationProperties来重构优
    @ConditionalOnProperty实现按需注入bean短信工具类SmsUtilzhenghe-common是一个基础包。SmsUtil坐落在zhenghe-common里。先看看Smsutil的面目。packagecom.emax......