<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-bean 和 third-bean 同时 third-bean 当作第三方 jar 包被 create-bean 援用,能够在这个 demo 上进行相干测试。
GitHub 我的项目源码: https://github.com/yudiandemi…
本文由博客一文多发平台 OpenWrite 公布!