如何将一个组件注册到容器中?Bean注解一招解决-

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将一个组件注册到容器中?Bean注解一招解决-相关的知识,希望对你有一定的参考价值。

参考技术A 通过组件扫描和自动注入已经大大简化了我们的开发,然而,Spring仍然不满足于此,经过版本的迭代,现在我们已经可以完全抛弃配置文件使用Spring进行开发了,一起来看看吧。

现在我们不创建Spring的配置文件,那么如何将一个组件注册到容器中呢?其实,我们仍然是需要一个配置文件的,不过这个配置文件能够以一个类的形式存在:

@Configuration用于将一个普通的Java类变为一个Spring的配置类,现在这个类就相当于之前的配置文件了,此时如果想注册一个组件,则使用@Bean注解:

这里需要注意几点,若有方法被@Bean注解标注,则该方法的返回值则为需要注册的组件,而方法名则为组件在容器中的名字,当然了,这些都需要建立在代码是写在配置类的前提下。

如果想要修改组件的名字,可以修改方法名:

若是不想修改方法名,@Bean注解也提供了修改名字的方式:

@Bean中还有initMethod和destroyMethod属性,它们分别用于指定组件的两个生命周期方法:

@ComponentScan注解是用来完成组件扫描的,它需要标注在配置类上:

它的作用等价于如下配置:

我们来聊一聊关于@ComponentScan的一些高级用法,该注解是可以在扫描时指定扫描规则的,比如我们想扫描 com.wwj.spring.demo 这个包,但是包里有一些类、或者一些注解的内容是我们不想要注册的,此时我们就可以指定扫描规则,如下:

在如上的配置中,excludeFilters用来配置需要排除的组件,需要借助@Filter注解,@Filter注解中的type属性用于指定以哪种方式排除组件,Spring一共提供了5种匹配方式:

所以如果想要具体排除某个组件,则使用ASSIGNABLE_TYPE,如果想要排除某个注解标注的所有组件,则使用ANNOTATION:

将excludeFilters切换为includeFilters,功能将变为只扫描匹配的组件,如下:

以上配置的作用是扫描 com.wwj.spring.demo 包下被@Service注解标注的组件,注意一点,由于Spring默认的扫描规则就是扫描所有带@Component注解的组件,所以若是想实现只扫描某个注解,则需要添加配置useDefaultFilters = false来禁用掉Spirng默认的扫描规则。

若是想实现自定义扫描规则,也非常简单,只需实现TypeFilter接口:

然后进行配置即可:

千万别忘了配置useDefaultFilters = false,此时将只能扫描到名字为user的组件。

这些内容在配置文件中也是可以进行配置的,简单举一个例子吧:

@Scope用于指定组件的作用域,关于作用域在上一篇我们已经介绍过了, 所以用法其实非常简单:

不过多介绍,但由此可以引申出一个新的注解: @Lazy ,该注解的作用是指定组件是否懒加载,默认情况下,所有组件会在容器启动的时候被创建,而如果标注@Lazy,则组件会在第一次使用时被创建。我们可以来试验一下,首先编写一个User类:

编写测试代码:

当没有添加@Lazy注解,控制台输出:

当添加了@Lazy注解,控制台没有任何输出,只有调用了 context.getBean_(_"user"_)_; User对象才会被创建。

@Conditional注解的功能是以指定的条件来注册组件,现在我们有两个组件:

一个是夏季水果西瓜,一个是冬季水果猕猴桃,现在有一个需求是当传入参数为夏天时,就注册西瓜,当传入参数是冬天时,就注册猕猴桃,该如何实现呢?

我们可以借助@Conditional注解来实现,首先创建类实现Condition接口:

接下来就可以使用它们进行配置了:

此时在虚拟机参数位置填写 -Dseason=summer ,Watermelon将被注册,当参数被修改为 -Dseason=winter 时,Kiwi将被注册,SpringBoot框架的底层就大量地使用到了这个注解,不过这是题外话了,我将在后续SpringBoot系统的文章中对其再度进行介绍。

我们已经知道,目前将一个组件注册到容器中有多种方式,使用@Bean或者组件扫描都可以,然而在某些情况下,这些方式都不太方便,比如将一个第三方的组件注册到容器中,此时我们可以借助@Import注解:

另一种方式是使用ImportSelector,创建类实现ImportSelector接口:

将需要注册到容器中的组件全类名写到数组中,然后@Import注解只需要填写这个类的信息即可:

还有一种方式是实现ImportBeanDefinitionRegistrar接口,它与第二种方式类似,与之不同的是,这种方式可以自定义组件注册到容器中的名字:

配置如下:

需要注意的是第一种和第二种方式注册的组件,其在容器中的名字是组件的全类名。

FactoryBean也是Spring提供的一种注册组件的方式,不过它比较特殊,看一个例子:

这三个方法非常好理解:

那有同学提出疑问了,这种方式岂不是更加麻烦了,有必要存在吗?当然有了,它牛就牛在你可以随意篡改需要注册的组件,比如:

现在看似注册的是User对象,其实注册的是Cat,不信我们试试:

运行结果:

若是想要获得实现了FactoryBean接口的User对象本身,则需要在名字面前添加 & :

运行结果:

以上是关于如何将一个组件注册到容器中?Bean注解一招解决-的主要内容,如果未能解决你的问题,请参考以下文章

String注解驱动开发如何按照条件向Spring容器中注册bean?这次我懂了!!

注解bean的用途

Spring注解驱动开发在@Import注解中使用ImportBeanDefinitionRegistrar向容器中注册bean

Spring 学习历程

spring利用注解来注册bean到容器

Spring注解——使用@ComponentScan自动扫描组件