SpringBoot原理前置知识-bean的8种加载方式

本文详细介绍了SpringBoot中bean的8种加载方式,包括XML配置、注解、配置类、@Import、registerBean()、ImportSelector接口、ImportBeanDefinitionRegistrar接口以及BeanDefinitionRegistryPostProcessor接口的使用,同时总结了如何通过条件注解来控制bean的加载。

一、复习spring的前置知识

Bean初始化
1.xml方式(先创一个spring工程项目导入依赖)

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.12</version>
    </dependency>
</dependencies>

(1).创建实体类

public class cat {
}
public class dog {
}

(2).书写spring的配置文件applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- xml方式声明自定义的bean   -->
    <bean id="cat" class="bean.cat"/>
    <bean  class="bean.dog"/>

    <!-- xml方式声明第三方的bean   -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"/>
</beans>

(3).获取bean


public class App1 {
    public static void main(String[] args) {
        ApplicationContext application=new ClassPathXmlApplicationContext("applicationContext1.xml");
        Object cat = application.getBean("cat");
        System.out.println(cat);
        final dog bean = application.getBean(dog.class);
        System.out.println(bean);
        //遍历所有定义的bean输出类名
        String[] name=application.getBeanDefinitionNames();
        for (String s : name) {
            System.out.println(s);
        }
    }
}

在这里插入图片描述
2.注解方式
自定义的类上加入注解@Component

@Component("tom")
public class cat {
}

第三方需自定义返回对象 加上@Bean,类上加上@Configuration或者@Component

package config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class DBConfig {
    @Bean
    public DruidDataSource dataSource(){
        return new DruidDataSource();
    }
}

使用直接配置文件需加入命名空间context,然后配置spring需要扫描注解的包

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">
  <context:component-scan base-package="bean config"/>
</beans>

打印

public class App2 {
    public static void main(String[] args) {
        ApplicationContext application=new ClassPathXmlApplicationContext("applicationContext2.xml");
        //遍历所有定义的bean输出类名
        String[] name=application.getBeanDefinitionNames();
        for (String s : name) {
            System.out.println(s);
        }
    }
}

在这里插入图片描述
3.配置类方式
使用配置类代替xml文件 @ComponentScan(“bean,config”)里面写需要加载的包

@ComponentScan("bean,config")
public class SpringConfig3 {

}

打印 使用new AnnotationConfigApplicationContext(SpringConfig3.class)加载配置类

public class App3 {
    public static void main(String[] args) {
        ApplicationContext application=new AnnotationConfigApplicationContext(SpringConfig3.class);
        //遍历所有定义的bean输出类名
        String[] name=application.getBeanDefinitionNames();
        for (String s : name) {
            System.out.println(s);
        }
    }
}

4.@import方式

@Import({dog.class,DBConfig.class})
public class SpringConfig4 {

}

@Import可以做到无侵入式编程 直接加载所需的类,被加载的类上不需要加注解

5.AnnotationConfigApplicationContext.registerBean()方式

public class App5 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext application=new AnnotationConfigApplicationContext(SpringConfig4.class);
        application.registerBean("cat", cat.class);
        //遍历所有定义的bean输出类名
        String[] name=application.getBeanDefinitionNames();
        for (String s : name) {
            System.out.println(s);
        }
    }
}

6.实现ImportSelector接口
通过ImportSelector可以实现对导入源的编程式处理
比如通过判断类上是否有@Configuration注解决定返回什么类型对象

public class MyImportSelector implements ImportSelector {
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        boolean flag = importingClassMetadata.hasAnnotation("org.springframework.context.annotation.Configuration");
        if (flag){
            return new String[]{"bean.dog"};
        }
        else {
            return new String[]{"bean.cat"};
        }
    }
}
@Configuration
@Import(MyImportSelector.class)
public class SpringConfig6 {

}
public class App6 {
    public static void main(String[] args) {
        ApplicationContext application=new AnnotationConfigApplicationContext(SpringConfig6.class);
        //遍历所有定义的bean输出类名
        String[] name=application.getBeanDefinitionNames();
        for (String s : name) {
            System.out.println(s);
        }
    }
}

7.实现ImportBeanDefinitionRegistrar接口
实现ImportBeanDefinitionRegistrar接口,通过BeanDefinition的注册器来注册实名bean,实现对容器中的bean的裁定,例如对现有bean的覆盖,进而达成不修改源代码的情况下更换实现的效果。

@Import(MyRegistrar.class)
public class SpringConfig7 {

}
public class MyRegistrar implements ImportBeanDefinitionRegistrar {

    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(dog.class).getBeanDefinition();
        registry.registerBeanDefinition("YELLOW",beanDefinition);
    }
}
public class App7 {
    public static void main(String[] args) {
        ApplicationContext application=new AnnotationConfigApplicationContext(SpringConfig7.class);
        //遍历所有定义的bean输出类名
        String[] name=application.getBeanDefinitionNames();
        for (String s : name) {
            System.out.println(s);
        }
    }
}

8.实现BeanDefinitionRegistryPostProcessorr接口
与7很相似,BeanDefinitionRegistryPostProcessor 是在对象在容器注册后进行后置处理,保证最后的实现内容是自己想要的。

public class MyProcess implements BeanDefinitionRegistryPostProcessor {
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(dog.class).getBeanDefinition();
        registry.registerBeanDefinition("YELLOW1",beanDefinition);
    }

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    }
}

总结

在这里插入图片描述
bean的加载控制
1.自己在对象注册时加上控制

在这里插入图片描述
2.使用springboot的condition注解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值