在SpringBoot的大环境下,基本上很少使用之前的xml配置Bean,主要是因为这种方式不好维护而且也不够方便。
springboto注入bean主要采用下图几种方式,
1、注解装配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实现不了的自定义加载类。