java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot bean加载

SpringBoot bean的多种加载方式示例详解

作者:冬天vs不冷

本文详细介绍了在SpringBoot中加载Bean的多种方式,包括通过xml配置文件、注解定义、特殊方式如FactoryBean、@ImportResource、ApplicationContext以及使用@Import注解导入bean的方法,感兴趣的朋友跟随小编一起看看吧

一、xml配置文件

配置文件spring-bean.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="person" class="com.xc.entity.Person"/>
    <bean class="com.xc.entity.Person"/>
    <bean class="com.xc.entity.Person"/>
    <!--xml方式声明第三方开发的bean-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"/>
</beans>

加载xml

public class App {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-bean.xml");
        for (String beanDefinitionName : context.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }
    }
}

输出结果:

person
com.xc.entity.Person#0
com.xc.entity.Person#1
dataSource

二、注解定义bean

1、使用AnnotationConfigApplicationContext对象加载

public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        for (String beanDefinitionName : context.getBeanDefinitionNames()) {
            System.err.println(beanDefinitionName);
        }
    }
}
public class MyConfig {
}

  使用AnnotationConfigApplicationContext对象加载MyConfig,即使MyConfig类什么注解没有,也会被注册为bean。

2、加载本地类 使用的注解@Component或其他衍生注解@Service@Controller@Repository

@Service
public class BookServiceImpl implements BookService {
}

3、加载第三方jar类

  由于我们无法在第三方提供的技术源代码中去添加上述4个注解,因此当你需要加载第三方开发的bean的时候可以使用@Component@Configuration都可以,一般引入第三方倾向于后者。

//@Component
@Configuration
public class DbConfig {
    @Bean
    public DruidDataSource dataSource(){
        return new DruidDataSource();
    }
    @Bean
    public Cat cat(){
    	Cat cat = new Cat();
    	cat.setDruidDataSource(dataSource());
    	return cat; 
    }
}

三、特殊方式

3.1、使用FactroyBean接口

public class DogFactoryBean implements FactoryBean<Dog> {
    //创建bean的复杂过程
    @Override
    public Dog getObject() throws Exception {
        Dog d = new Dog();
        //.........
        return d;
    }
    //bean的类型
    @Override
    public Class<?> getObjectType() {
        return Dog.class;
    }
    //bean是否单例
    @Override
    public boolean isSingleton() {
        return true;
    }
}

配置类

public class MyConfig {
    @Bean
    public DogFactoryBean dog(){
        return new DogFactoryBean();
    }
}

启动类

public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        System.out.println(context.getBean("dog"));
    }
}

3.2、注解导入XML格式配置的bean

@Configuration
@ImportResource(locations = "spring-bean.xml")
public class SpringConfig {
}

3.3、通过上下文ApplicationContext注册bean

在容器初始化完成后手动加载bean,创建方式很多

在这里插入图片描述

方式一:无参构造

public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        //上下文容器对象已经初始化完毕后,手工加载bean
        ctx.register(Mouse.class);
    }
}

方式二:多参构造

public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        //上下文容器对象已经初始化完毕后,手工加载bean
        ctx.registerBean("tom", Cat.class,"花猫",3);
    }
}

四、@Import注解注入bean

1、@Import导入普通类

@Configuration
//@Import(Pig.class)
@Import({Dog.class,Cat.class})
public class MyConfig {
}
public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        for (String beanDefinitionName : context.getBeanDefinitionNames()) {
            System.err.println(beanDefinitionName);
        }
    }
}

输出结果:

myConfig
com.xc.springboot.bean.Dog
com.xc.springboot.bean.Cat

2、@Import导入实现了ImportSelector接口的类

public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata metadata) {
        System.out.println("元数据Class名称:" + metadata.getClassName());
        //各种条件的判定,判定完毕后,决定是否装载指定的bean
        boolean flag = metadata.hasAnnotation("org.springframework.context.annotation.Configuration");
        if(flag){
            return new String[]{"com.xc.springboot.bean.Dog"};
        }
        return new String[]{"com.xc.springboot.bean.Cat"};
    }
}

配置类

@Configuration
@Import(MyImportSelector.class)
public class MyConfig {
}

启动类

public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        for (String beanDefinitionName : context.getBeanDefinitionNames()) {
            System.err.println(beanDefinitionName);
        }
    }
}

输出结果:

元数据Class名称:com.xc.springboot.bean.MyConfig
myConfig
com.xc.springboot.bean.Dog

3、@Import导入实现了ImportBeanDefinitionRegistrar接口的类

public class MyRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        BeanDefinition beanDefinition = 	
            BeanDefinitionBuilder.rootBeanDefinition(BookService.class).getBeanDefinition();
        registry.registerBeanDefinition("bookService",beanDefinition);
    }
}

4、@Import导入实现了BeanDefinitionRegistryPostProcessor接口的类

public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        // 通过 BeanDefinitionBuilder 创建一个新的 Bean 定义
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MyCustomBean.class);
        // 注册这个 bean 定义到 registry 中
        registry.registerBeanDefinition("myCustomBean", builder.getBeanDefinition());
        System.out.println("Bean definition registered: myCustomBean");
    }
    @Override
    public void postProcessBeanFactory(org.springframework.beans.factory.config.ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 在这里可以对 BeanFactory 进行进一步的配置
        System.out.println("Bean factory post-processing");
    }
}

注意:所有通过@Import导入的bean名称为全路径名

到此这篇关于SpringBoot基础(四):bean的多种加载方式的文章就介绍到这了,更多相关SpringBoot bean加载方式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文