美文网首页
Spring:装配Bean

Spring:装配Bean

作者: engineer_tang | 来源:发表于2021-12-04 12:20 被阅读0次

    1. 装配Bean

    三种装配机制:

    • 在XML中进行显式配置;
    • 在Java中进行显式配置;
    • 隐式的bean发现机制和自动装配。

    1.1 自动化装配Bean

    最强大的是Spring自动化装配,从以下两个方面实现自动化装配:

    • 组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean。
    • 自动装配(autowiring):Spring自动满足bean之间的依赖。

    组件扫描启动需要配置:

    @Configuration
    @ComponentScan
    public class CDPlayerConfig {}
    

    默认扫描配置类所在包及其所有子包带有@Component注解的类。

    1.2 为bean命名

    Spring默认bean名称为类名的第一个字母小写的名称,可进行自命名,如下:

    @Component("lonelyHeartsClub")
    public class SgtPeppers {
    }
    

    另一种命名方案:@Named("abc"),可自行查阅。

    1.3 设置组件扫描基础包

    根据字符串

    @Configuration
    @ComponentScan("soundsystem")
    public class CDPlayerConfig {}
    

    或者

    @Configuration
    @ComponentScan(basePackages="soundsystem")
    public class CDPlayerConfig {}
    

    针对扫描多个基础包的情况如下:

    @Configuration
    @ComponentScan(basePackages={"soundsystem", "video"})
    public class CDPlayerConfig {}
    

    根据类型
    根据类所在的包作为扫描基础包

    @Configuration
    @ComponentScan(basePackages={CDPlayer.class, DVDPlayer.class})
    public class CDPlayerConfig {}
    

    2. 通过为bean添加注解实现自动装配

    通过@Autowired注解进行自动装配,
    required属性:默认为true,不存在bean会抛出异常。
    也可使用@Inject.

    3. 通过Java代码装配bean

    将第三方库中的组件装配到自己的应用中。

    3.1 创建配置类

    @Configuration
    public class CDPlayerConfig {
    
      @Bean
      public CompactDisc sgtPeppers() {
        return new SgtPeppers();
      }
    }
    

    默认情况下,bean的ID与带有@Bean注解的方法名是一样的,可自定义命名,如下:

    @Configuration
    public class CDPlayerConfig {
    
      @Bean(name="lonelyHeartsClubBand")
      public CompactDisc sgtPeppers() {
        return new SgtPeppers();
      }
    }
    

    3.2 借助JavaConfig实现注入

    第一种:直接引用创建bean的方法

    @Bean
    public CDPlayer cdPlayer() {
      return new CDPlayer(sgtPeppers());
    }
    

    因为sgtPeppers()方法上添加了@Bean注解,Spring将会拦截所有对它的调用,并确保直接返回该方法所创建的bean,而不是每次都对其进行实际的调用。

    第二种:直接通过方法参数:

    @Bean
    public CDPlayer cdPlayer(CompactDisc compactDisc) {
      return new CDPlayer(sgtPeppers());
    }
    

    4. 环境与profile

    通过@Profile注解指定某个bean属于哪一个profile,该注解能用于类上,也能用于方法上。

    4.1 激活profile

    确定profile的激活状态时,需要依赖两个独立的属性:spring.profiles.active和spring.profiles.default。如果设置了spring.profiles.active属性的话,那么它的值就会用来确定profile的激活。但如果没有设置spring.profiles.active属性的话,那么spring将查找spring.profiles.default的值。

    5. 条件化bean

    通过@Conditional注解实现,如下:

    @Bean
    @Conditional(MagicExistsCondition.class)
    public MagicBean magicBean() {
      return new MagicBean();
    }
    

    MagicExistsCondition的代码如下:

    public class MagicExistsCondition implements Condition {
      public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Environment env = context.getEnvironment();
        return env.containsProperty("magic");
      }
    }
    

    6. 处理自动装配的歧义性

    6.1 标示首选的bean

    直接在bean上加@Primary注解,来避免歧义性。

    @Bean
    @Primary
    public MagicBean magicBean() {
      return new MagicBean();
    }
    

    6.2 限定自动装配的bean

    使用@Qualifier注解限定符来缩小范围,达到限制条件锁位为一个bean的目的。

    @Autowired
    @Qualifier("iceCream")
    public void setDessert(Dessert dessert) {
       this.dessert = dessert;
    }
    

    如果没有指定bean限定符的情况下,所有的bean都会给定一个默认的限定符,它的值和bean ID相同。

    6.3 创建自定义限定符

    @Component
    @Qualifier("cold")
    public class IceCream implements Dessert {...}
    

    6.4 使用自定义的限定符注解

    通过创建自定义注解,使用@Qualifier注解来标注,它们就具有了@Qualifier注解的特性,它们本身实际上就成为了限定符注解。

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Qualifier
    public @interface Cold {
    }
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Qualifier
    public @interface Creamy {
    }
    

    使用的时候如下:

    @Component
    @Cold
    @Fruity
    public void Popsicle implements Dessert {...}
    

    装配如下:

    @Autowired
    @Cold
    @Creamy
    public void setDessert(Dessert dessert) {
      this.dessert = dessert;
    }
    

    7. bean的作用域

    默认情况下,所有bean都是以单例的形式进行创建的,Spring一共定义了四种作用域,如下:

    • 单例(Singleton):只创建一个实例。
    • 原型(Prototype):每次注入都会创建一个新的bean实例。
    • 会话(Session):在web应用中,为每个会话创建一个bean实例。
    • 请求(Request):为每个请求创建一个bean实例。
    @Component
    @Scopt(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public class Notepad {...}
    

    相关文章

      网友评论

          本文标题:Spring:装配Bean

          本文链接:https://www.haomeiwen.com/subject/nrpvxrtx.html