美文网首页
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