前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot引入Bean组件的几种方式

SpringBoot引入Bean组件的几种方式

作者头像
简单的程序员
发布2020-04-18 00:29:31
1.3K0
发布2020-04-18 00:29:31
举报
文章被收录于专栏:奕仁专栏奕仁专栏奕仁专栏

众所周知,在spring内部,所有的bean都是交由spring来统一管理的,有些bean可能是直接通过BeanDefinitionRegistry定义的,有些是通过FactoryBean注册的(一般用作其他框架与spring整合)

1、Spring引入bean组件的三种方式

引入@Import注解

实现FactoryBean 接口

以springboot为例,当一个配置类需要导入另外一个组件的时候,可以使用上面的方式进行导入。当然,spring为我们提供了一系列的注解,在引入其他组件的时候,可以使用@Import注解: 下面是Import注解的源码:

点开@Import注解源码,可以看到

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
	
	/**
	 * 除了直接在配置类上,还可以实现ImportSelector ,ImportBeanDefinitionRegistrar接口
	 * {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar} 
	 */
	Class<?>[] value();

}

看了上面的源码之后,我们现在有了三种选择,分别是下面的三种引入方式

1) 直接引入源class

@Import(value = {UserInput.class})
public class MovieApplication {
	public static void main(String[] args) {
		ApplicationContext context = SpringApplication.run(MovieApplication.class, args);
	}
}

2) 实现ImportSelector接口,手动定义bean

package org.choviwu.movie.config;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.annotation.Order;
import org.springframework.core.type.AnnotationMetadata;

public class MovieImportSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
		//注册一个字符串数组(数组格式为类的全路径),数组不能为null
        return new String[]{"org.choviwu.movie.model.Articles"};
    }
}

3) 实现ImportBeanDefinitionRegistrar接口,动态定义bean

package org.choviwu.movie.config;
 
public class MovieImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
                                        BeanDefinitionRegistry registry) {
		//利用bean定义注册类注册,可以进行bean的别名设置
        boolean flagArticle = registry.containsBeanDefinition("org.choviwu.movie.model.Articles");

        if(!flagArticle) {
            BeanDefinition definition = new RootBeanDefinition(Articles.class);
            registry.registerBeanDefinition("articles",definition);
        }

    }
}

4) 实现FactoryBean接口

package org.choviwu.movie.config;

import org.choviwu.movie.model.Config;
import org.springframework.beans.factory.FactoryBean;
//这种方式适合框架与spring整合
public class MovieFactoryBean implements FactoryBean<Config> {

  //这个方法是创建定义bean,也是实际执行的方法
    @Override
    public Config getObject() throws Exception {
        Config config = new Config();
        return config;
    }
	//类的类型
    @Override
    public Class<?> getObjectType() {
        return Config.class;
    }
	//单例模式
    @Override
    public boolean isSingleton() {
        return true;
    }
}

编写main方法,执行定义的bean

package org.choviwu.movie; 

import lombok.extern.slf4j.Slf4j;
import java.util.List;

@SpringBootApplication  
//这里分别引入了上面的三种组件方式
@Import(value = {UserInput.class,
		MovieImportSelector.class,
		MovieImportBeanDefinitionRegistrar.class}) 
//
public class MovieApplication {

	public static void main(String[] args) {
		ApplicationContext context = SpringApplication.run(MovieApplication.class, args);
		UserInput us = context.getBean(UserInput.class);
		UserInput us2 = context.getBean(UserInput.class);
		Articles articles= context.getBean(Articles.class);
		//这里返回的是实际注册的对象,也就是getObject的返回值
		Object obj =  context.getBean("movieFactoryBean");
		//这里返回一个movieFactoryBean对象,为什么加&符号呢? 可以查看BeanFactory源码查看定义
		Object obj2 =  context.getBean("&movieFactoryBean");
		System.out.println(us==us2);
		System.out.println(articles);
		System.out.println(obj);
		System.out.println(obj2);
	}
	//第四种方式,实现工厂bean方式,
	@Bean
	public MovieFactoryBean movieFactoryBean(){
		return new MovieFactoryBean();
	}
 
	@Bean 
	public UserInput userInput(){
		System.out.println(".........................................啊");
		return new UserInput();
	}
}

执行main方法结果如下:

true
org.choviwu.movie.model.Articles@138aa3cc
org.choviwu.movie.model.Config@5382184b
org.choviwu.movie.config.MovieFactoryBean@36417a54
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-04-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、Spring引入bean组件的三种方式
    • 引入@Import注解
      • 实现FactoryBean 接口
        • 1) 直接引入源class
        • 2) 实现ImportSelector接口,手动定义bean
        • 3) 实现ImportBeanDefinitionRegistrar接口,动态定义bean
        • 4) 实现FactoryBean接口
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档