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