乐趣区

关于java:SpringBoot引入第三方jar的Bean的三种方式

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

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

一、注解拆卸 Bean

1、应用 @Component 等派生注解

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

@Component
public 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,通常应用姿式以下

@Data
public class ConfigDemoBean {
}

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

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

3、@Component VS @Bean

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

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

比方

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

再比方

@Bean
public 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;
    }
}



@Configuration
public 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 包的我的项目应用
 */
@Component
public 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 公布!

退出移动版