<img src="http://www.image.jincou.com/e6ad88b51f294ed580e3c5b4f4c1471b" width="700" height="234">

在SpringBoot的大环境下,基本上很少应用之前的xml配置Bean,次要是因为这种形式不好保护而且也不够不便。 因而本篇博文也不再介绍Spring中通过xml来申明bean的应用形式。

一、注解拆卸Bean

1、应用@Component等派生注解

只有在类上加类上加 @Component 注解即可,该注解只有被扫描到就会注入到spring的bean容器中。

@Componentpublic class AnoDemoBean {}

当然不只是@Component注解能够申明Bean,还有如:@Repository@Service@Controller 等罕用注解同样能够。

如果去看这些注解,就发现这些注解上自身就有加 @Component 注解

@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Component   //能够看到@Service注解上有增加@Component,  @Repository和@Controller也一样。        public @interface Service {    @AliasFor(        annotation = Component.class    )    String value() default "";}

这系列注解的呈现,给咱们带来了极大的便当。咱们不须要像以前那样在bean.xml文件中配置bean了,当初只用在类上加上相干注解,就能轻松实现bean的定义。

这四种注解在性能上其实没有特地的区别,不过在业界有个不成文的约定:

  • Controller 个别用在管制层
  • Service 个别用在业务层
  • Repository 个别用在数据层
  • Component 个别用在公共组件上

2、@Bean定义形式

这种形式,次要是联合Configuration来定义bean,首先是申明一个配置类,而后再配置类中,通过返回bean对象的办法模式来申明bean,通常应用姿式以下

@Datapublic class ConfigDemoBean {}@Configurationpublic class BeanLoadConfig {    @Bean    public ConfigDemoBean configDemoBean() {        return new ConfigDemoBean();    }}

须要阐明的一点是BeanLoadConfig类本人也被Spring容器看为一个Bean。

3、@Component VS @Bean

1)作用对象不同:@Component 注解作用于类,而 @Bean 注解作用于办法

这样的特点会让 @Bean 形式更加灵便。比方当咱们援用第三方库中的类须要拆卸到 Spring 容器时,只能通过 @Bean 来实现。

比方

@Configurationpublic class WireThirdLibClass {    @Bean    public ThirdLibClass getThirdLibClass() {        //第三方的ThirdLibClass类        return new ThirdLibClass();    }}

再比方

@Beanpublic OneService getService(status) {    case (status)  {        when 1:                return new serviceImpl1();        when 2:                return new serviceImpl2();        when 3:                return new serviceImpl3();    }}

这两点都是@Component无奈做到,只能@Bean实现,所以说@Bean更加灵便。

2)@Component通常是通过类门路扫描来主动拆卸到Spring容器中。而@Bean通常咱们会在该注解的办法中定义产生这个bean的逻辑。

咱们能够加一些@Conditional,@ConditionalOnBean等等一些注解来管制是否申明该Bean,不会一开始就主动拆卸到Spring容器中。

比方

public class MacCondition implements Condition {   @Override    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {        Environment environment = conditionContext.getEnvironment();        String property = environment.getProperty("os.name");        if (property.contains("Mac")) {            log.info("以后操作系统是:Mac OS X");            return true;        }        return false;    }}@Configurationpublic class ConditionalConfig {    /**     * 如果MacCondition的实现办法返回true,则注入这个bean     */    @Bean("mac")    @Conditional({MacCondition.class})    public SystemBean systemMac() {        log.info("ConditionalConfig办法注入 mac实体");        return new SystemBean("Mac ios零碎","001");    }}

下面的例子示意,如果以后操作系统是Mac,才会注入以后Bean。这个也只能 @Bean 注解能力实现。

总结:@Component和@Bean都是用来注册Bean并拆卸到Spring容器中,然而Bean比Component的自定义性更强。能够实现一些Component实现不了的自定义加载类。


二、引入内部jar包的Bean

如果下面的注解加在以后我的项目中那么当SpingBoot主类启动的时候,@SpringBootApplication注解会默认去扫描的本包它的子包的所有须要拆卸的类,主动拆卸到spring的bean容器中。

然而如果你提供了一个Jar包供第三方用户应用,那么你这个jar包中的Bean,能被第三方加载么?

这就要看你以后我的项目的包名和你你援用的第三方Jar包的包名了。

如果你以后我的项目本包的地址是com.jincou 而你援用的第三方Jar的本包是 com.third,那么也就是第三方Jar的Bean无奈被扫描到,所以也就无奈注入到Spring容器中。

比方这里有个第三方的Bean。要如何做能力被扫描注入到Spring容器中呢。

package com.third.bean;import org.springframework.stereotype.Component;/** * @Description: 这个bean作为第三方bean 给依赖该jar包的我的项目应用 */@Componentpublic class ThirdComponentBean {    private String type = "第三方ThirdComponent注解生成bean实体";}

1、@ComponentScan

很简略,既然@SpringBootApplication注解默认扫描只是以后我的项目的本包它的子包,那就想方法让它扫描第三方jar的包就好了。

/** * @Description: Springboot 启动类 */@ComponentScan(basePackages ={"com.third.bean"})@SpringBootApplication()public class Application {    public static void main(String[] args) {        SpringApplication.run(Application.class);    }}

@ComponentScan次要就是定义扫描的门路从中找出标识了须要拆卸的类主动拆卸到spring的bean容器中。

须要拆卸的类也就是下面加了@Controller,@Service,@Repository,@Component,@Configuration等等的注解的Bean到IOC容器中。

这里不肯定要加在启动类上,你能够加在加在拆卸的类上,但倡议加在启动类上,比拟直观,前期如果要改变或者去除也比拟好找。

2、@Import注解

@ComponentScan是扫描整个包,但其实你可能只需注入一个或者几个指定的Bean,那咱们能够思考用 @Import 注解

@Import(value= com.third.bean.ThirdComponentBean.class)@SpringBootApplication()public class Application {    public static void main(String[] args) {        SpringApplication.run(Application.class);    }}

这样做同样也会胜利的将ThirdComponentBean对象注入到Spring的bean容器中。

3、spring.factories

下面两种注入形式都有个很显著毛病,就是如果我须要援用内部jar包的Bean的时候,都须要在以后我的项目配置 @ComponentScan 或者 @Import 去扫描能力注入以后Bean,这样显然不够敌对。

可不可以以后我的项目什么都不做就能够间接援用第三方jar的Bean呢?

当然能够。

咱们只须要在将配置放在第三方jar指定的文件中即可,使用者会主动加载,从而防止的代码的侵入

  • 在资源目录下新建目录 META-INF
  • 在 META-INF 目录下新建文件 spring.factories
  • 在文件中增加上面配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.third.bean.ConfigurationBean

<img src="http://www.image.jincou.com/5a1be2b260604f3bbac69beae6eac318" width="400" height="250">

残缺我的项目

相干demo我的项目曾经放到gitHub上,这里创立了两个我的项目 create-beanthird-bean 同时third-bean当作第三方jar包被create-bean援用,能够在这个demo上进行相干测试。

GitHub我的项目源码: https://github.com/yudiandemi...

本文由博客一文多发平台 OpenWrite 公布!