page contents

Spring 的这些核心注解你了解吗?

我们可以使用org.springframework.beans.factory.annotation和org.springframework.context.annotation包中的注释来利用Spring DI引擎的功能。我们经常将这些称为“Spring核心注释”。 >>D...

我们可以使用org.springframework.beans.factory.annotationorg.springframework.context.annotation包中的注释来利用Spring DI引擎的功能。我们经常将这些称为“Spring核心注释”。

>>DI相关注释

1. @Autowired

我们可以使用@Autowired来标记Spring将要解析和注入的依赖项。我们可以将这个注释与构造函数,setter或字段注入一起使用。构造函数注入:



class Car {
Engine engine;

@Autowired
Car(Engine engine) {
this.engine = engine;
}
}

设值注入:



class Car {
Engine engine;

@Autowired
void setEngine(Engine engine) {
this.engine = engine;
}
}

字段注入:



class Car {
@Autowired
Engine engine;
}

@Autowired有一个名为required的布尔参数,默认值为true当它没有找到合适的bean来连接时,它会调整Spring的行为。如果为true,则抛出异常,否则没有任何连线。注意,如果我们使用构造函数注入,则所有构造函数参数都是必需的。从版本4.3开始,除非我们声明至少两个构造函数,否则我们不需要显式地使用@Autowired注释构造函数。

2. @Bean

当需要返回类型的新实例时,Spring会调用这些方法。生成的bean与工厂方法具有相同的名称。如果我们想以不同的方式命名,我们可以使用此批注的名称或值参数(参数值是参数名称的别名):



@Bean("engine")
Engine getEngine() {
return new Engine();
}

请注意,所有使用@Bean注释的方法都必须在@Configuration类中。

3. @Qualifier

我们使用@Qualifier@Autowired来提供我们想要在不明确的情况下使用的bean id或bean名称。例如,以下两个bean实现相同的接口:



class Bike implements Vehicle {}

class Car implements Vehicle {}

如果Spring需要注入一个Vehicle bean,它最终会有多个匹配的定义。在这种情况下,我们可以使用@Qualifier注释显式提供bean的名称。使用构造函数注入:



@Autowired
Biker(@Qualifier("bike") Vehicle vehicle) {
this.vehicle = vehicle;
}

设值注入:



@Autowired
void setVehicle(@Qualifier("bike") Vehicle vehicle) {
this.vehicle = vehicle;
}

另外:



@Autowired
@Qualifier("bike")
void setVehicle(Vehicle vehicle) {
this.vehicle = vehicle;
}

使用字段注入:



@Autowired
@Qualifier("bike")
Vehicle vehicle;

4. @Required

@Required用于标记我们想要通过XML填充的依赖项的setter方法:



@Required
void setColor(String color) {
this.color = color;
}



<bean class="com.baeldung.annotations.Bike">
<property name="color" value="green" />
</bean>

否则,将抛出BeanInitializationException

5. @Value

我们可以使用@Value将属性值注入bean。它与构造函数,setter和字段注入兼容。

构造函数注入:



Engine(@Value("8") int cylinderCount) {
this.cylinderCount = cylinderCount;
}

设值注入:



@Autowired
void setCylinderCount(@Value("8") int cylinderCount) {
this.cylinderCount = cylinderCount;
}

或者:



@Value("8")
void setCylinderCount(int cylinderCount) {
this.cylinderCount = cylinderCount;
}

字段注入:



@Value("8")
int cylinderCount;

当然,注入静态值是没有用的。因此,我们可以使用@Value中的占位符字符串来连接外部源中定义的值,例如,在.properties.yaml文件中。我们假设以下.properties文件:



engine.fuelType=petrol

我们可以使用以下内容注入engine.fuelType的值:



@Value("${engine.fuelType}")
String fuelType;

6. @DependsOn

我们可以使用这个注释使Spring在注释之前初始化其他bean。通常,此行为是自动的,基于bean之间的显式依赖关系。当依赖项是隐式时,我们只需要这个注释,例如,JDBC驱动程序加载或静态变量初始化。

我们可以在依赖类上使用@DependsOn来指定依赖关系bean的名称。注释的value参数需要一个包含依赖项bean名称的数组:



@DependsOn("engine")
class Car implements Vehicle {}

或者,如果我们使用@Bean批注定义bean,则应使用@DependsOn注释工厂方法:



@Bean
@DependsOn("fuel")
Engine engine() {
return new Engine();
}

7. @Lazy

当我们想要懒惰地初始化我们的bean时,我们使用@Lazy默认情况下,Spring会在应用程序上下文的启动/引导时急切地创建所有单例bean。

但是,有些情况下我们需要在请求时创建bean,而不是在应用程序启动时。

此注释的行为会有所不同,具体取决于我们准确放置它的位置。我们可以说:

一个@Bean带注释的bean工厂方法,用于延迟方法调用(因此创建bean) 一个@Configuration类,所有包含的@Bean方法都会受到影响 一个@Component类,它不是@Configuration类,这个bean将被懒惰地初始化 @Autowired构造函数,setter或字段,懒惰地加载依赖项(通过代理)此批注具有名为value的参数,其默认值为true。

覆盖默认行为很有用。例如,在全局设置为惰性时标记要急切加载的bean,或者在@Lazy标记的@Configuration类中将特定的@Bean方法配置为急切加载:



@Configuration
@Lazy
class VehicleFactoryConfig {

@Bean
@Lazy(false)
Engine engine() {
return new Engine();
}
}

8. @Lookup

使用@Lookup注释的方法告诉Spring在调用它时返回方法返回类型的实例。

9. @Primary

有时我们需要定义多个相同类型的bean。在这些情况下,注入将失败,因为Spring不知道我们需要哪种bean。我们已经看到了一个处理这种情况的选项:@Qualifier标记所有接线点并指定所需bean的名称。但是,大多数时候我们需要一个特定的bean而很少需要其他bean。我们可以使用@Primary来简化这种情况:如果我们用@Primary标记最常用的bean,它将在不合格的注入点上选择:



@Component
@Primary
class Car implements Vehicle {}

@Component
class Bike implements Vehicle {}

@Component
class Driver {
@Autowired
Vehicle vehicle;
}

@Component
class Biker {
@Autowired
@Qualifier("bike")
Vehicle vehicle;
}

在前面的例子中,汽车是主要的载体。因此,在Driver类中,Spring注入了一个Car bean。当然,在Biker bean中,现场车辆的价值将是一个Bike对象,因为它是合格的。

10. @Scope

我们使用@Scope来定义@Component类的范围或@Bean定义。它可以是单例,原型,请求,会话,globalSession或某些自定义范围。例如:



@Component
@Scope("prototype")
class Engine {}

>>上下文配置注释

我们可以使用本节中描述的注释配置应用程序上下文。

1. @Profile

如果我们希望Spring仅在特定配置文件处于活动状态时使用@Component类或@Bean方法,我们可以使用@Profile标记它。我们可以使用注释的value参数配置配置文件的名称:



@Component
@Profile("sportDay")
class Bike implements Vehicle {}

2. @Import

我们可以使用特定的@Configuration类,而不使用此批注进行组件扫描。我们可以为这些类提供@Import的value参数:



@Import(VehiclePartSupplier.class)
class VehicleFactoryConfig {}

3. @ImportResource

我们可以使用此批注导入XML配置。我们可以使用locations参数或其别名value参数指定XML文件位置:



@Configuration
@ImportResource("classpath:/annotations.xml")
class VehicleFactoryConfig {}

4. @PropertySource

使用此注释,我们可以为应用程序设置定义属性文件:



@Configuration
@PropertySource("classpath:/annotations.properties")
class VehicleFactoryConfig {}

@PropertySource利用Java 8重复注释功能,这意味着我们可以多次使用它标记一个类:



@Configuration
@PropertySource("classpath:/annotations.properties")
@PropertySource("classpath:/vehicle-factory.properties")
class VehicleFactoryConfig {}

5. @PropertySources

我们可以使用此批注指定多个@PropertySource配置:



@Configuration
@PropertySources({
@PropertySource("classpath:/annotations.properties"),
@PropertySource("classpath:/vehicle-factory.properties")
})
class VehicleFactoryConfig {}

注意,自Java 8以来,我们可以通过如上所述的重复注释功能实现相同的功能。

  • 发表于 2020-01-18 14:29
  • 阅读 ( 846 )
  • 分类:Java开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

1135 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1470 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章