查看原文
其他

Spring注入Bean的方式你知道几种?

Mr.Fire 架构师成长之路 2023-09-18

点击蓝字

关注我们


前言

Spring作为Java程序员必备,核心之一就是Spring的IOC思想,对象的创建都依赖于Spring容器,那么注入一个baen到容器中有哪些方法呢,你知道几种,一起来看看。


1.XML方式

最早接触Java还是ssh那一套,所有bean都是依赖xml配置的方式注入的,而xml又可以有四种方式:Set方法注入,构造方法注入,静态工厂注入和非静态工厂注入。这里以Set方法注入为例:

<bean name="product" class="com.fire.bean.Product"> <property name="name" value="电脑"></property></bean>
/** * @Author Mr.Fire * @Desc * @Date 2022/7/21 */@Datapublic class Product {
private String id;
private String name;}

2.@ComponentScan+注解

里说的注解就是我们常用的@Component以及他的派生@Controller、@Service、@Repository。这就不多说了。


3.JavaConfig注入

JavaConfig即java的配置类,@Configuration+@Bean注解的方式注入bean,可替代以往繁琐的xml形式。

/** * @Author Mr.Fire * @Desc * @Date 2022/7/21 */@Configurationpublic class BeanConfig { @Bean public Product product(){ return new Product(); }}


4.@Import注解

1)导入普通类

Sping4.2后,@Import可以注入普通类的bean实例

/** * @Author Mr.Fire * @Desc * @Date 2022/7/21 */public class Order {    ...}
@Import({Order.class})@Configurationpublic class BeanConfig {
@Bean public Product product(){ return new Product(); }}

这样就可以在其他地方注入Order这个bean使用了,是不是很神奇。如果要注入多个bean也是可以的,@Import注解的value是个数组。


2)导入Configuration类

更高端的玩法,我们还可以注入Configuration类,比如@EnableSwagger2注解中导入了Swagger2DocumentationConfiguration类。

该类是一个Configuration类,它又导入了另外两个类:

  • SpringfoxWebMvcConfiguration

  • SwaggerCommonConfiguration



3)导入ImportSelector接口实现类

在SpringBoot启动注解中往下找,@EnableAutoConfiguration注解中就有使用,这也是自动装配重要的一环,关于自动装配可看这篇文章SpringBoot自动装配

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@AutoConfigurationPackage@Import(AutoConfigurationImportSelector.class)public @interface EnableAutoConfiguration { ...}


4)导入ImportBeanDefinitionRegistrar接口实现类

public class CustomImportSelector implements ImportBeanDefinitionRegistrar {
@Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { RootBeanDefinition roleBeanDefinition = new RootBeanDefinition(Role.class); registry.registerBeanDefinition("role", roleBeanDefinition);
RootBeanDefinition userBeanDefinition = new RootBeanDefinition(User.class); userBeanDefinition.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE); registry.registerBeanDefinition("user", userBeanDefinition); }}

重写registerBeanDefinitions方法,在该方法中我们可以获取BeanDefinitionRegistry对象,通过它去注册bean。不过在注册bean之前,我们先要创建BeanDefinition对象,它里面可以自定义bean的名称、作用域等很多参数

然后在MyConfig类上导入上面的类:

@Import({CustomImportSelector.class})@Configurationpublic class MyConfig {}


5.实现BeanDefinitionRegistryPostProcessor

Spring提供的bean注册接口,注释描述:修改应用程序上下文的内部bean定义注册表标准初始化。所有常规bean定义都将被加载,但是还没有bean被实例化。这允许进一步添加在下一个后处理阶段开始之前定义bean。在该方法中能够获取BeanDefinitionRegistry对象,它负责bean的注册工作。


另外,BeanFactoryPostProcessor 也可以注册bean。


既然这两个接口都能注册bean,那么他们有什么区别?

  • BeanDefinitionRegistryPostProcessor 更侧重于bean的注册

  • BeanFactoryPostProcessor 更侧重于对已经注册的bean的属性进行修改,虽然也可以注册bean。


6.实现FactoryBean

实现FactoryBean的两个方法

/** * @Author Mr.Fire * @Desc * @Date 2022/7/21 */public class TestBeanFactory implements FactoryBean { @Override public Object getObject() throws Exception { return new Product(); }
@Override public Class<?> getObjectType() { return Product.class; }
@Override public boolean isSingleton() { return true; }}

在之前的Config类中注入testFactoryBeran

/** * @Author Mr.Fire * @Desc * @Date 2022/7/21 */@Import({Order.class})@Configurationpublic class BeanConfig {
@Bean public Product product(){ return new Product(); } @Bean public TestBeanFactory testBeanFactory(){ return new TestBeanFactory(); }}


总结

以上就是今天介绍的几种注入Bean的几种方式,也是面试八股文之一吧,你知道几种呢。


 THE END

推荐阅读  

SpringBoot 中如何正确的在异步线程中使用request

官方自爆了!去年的B站原来是这样崩溃的……

阿里出品!SpringBoot应用自动化部署神器

RabbitMQ如何实现高可用?

面试必问之Redis底层是怎么实现的?

点赞+在看 ,关注公众号回复“666”领取福利


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存