Spring 注解翻译
这里罗列一些Spring的注解,不断巩固
Spring Core Annotations
概述
我们可以使用 org.springframework.beans.factory.annotation
和org.springframework.context.annotation
包中的注释来利用Spring DI引擎的功能。
称之为spring核心注解(Spring core annotations)
依赖注入相关注释
@Autowired
我们可以使用@Autowired标记Spring将要解析和注入的依赖项。我们可以将这个注释与构造函数,setter或字段注入一起使用。
构造方法注入:
class Car {
Engine engine;
@Autowired
Car(Engine engine) {
this.engine = engine;
}
}
setter方法注入
class Car {
Engine engine;
@Autowired
void setEngine(Engine engine) {
this.engine = engine;
}
}
属性注入
class Car {
@Autowired
Engine engine;
}
@Autowired有默认为required的布尔参数,默认值为true。当它没有找到合适的bean,如果为true,则抛出异常。
如果使用构造函数注入,则所有构造函数参数都是必需的。
从版本4.3开始,除非我们声明至少两个构造函数,否则我们不需要显式地使用@Autowired注释构造函数。
@Autowired and constructor injection相关详细内容
@Bean
@Bean标记了一个实例化Spring bean的工厂方法
@Bean
Engine engine() {
return new Engine();
}
当需要返回类型的新实例时,Spring会调用这些方法。
生成的bean与工厂方法具有相同的名称。如果我们想以不同的方式命名,我们可以使用此注解的名称或值参数(参数值是参数名称的别名)
@Bean("engine")
Engine getEngine() {
return new Engine();
}
注意,所有使用@Bean注释的方法都必须在@Configuration类中。
@Qualifier
使用@Autowired 不确定bean id 或 bean name时,可以使用Qualifier来显式指定。
、、两个bean实现相同的接口
class Bike implements Vehicle {}
class Car implements Vehicle {}
如果Spring需要注入一个Vehicle bean,它最终会有多个匹配的定义。在这种情况下,我们可以使用@Qualifier注释显式提供bean的名称。
构造方法注入
@Autowired
Biker(@Qualifier("bike") Vehicle vehicle) {
this.vehicle = vehicle;
}
setter方法注入
@Autowired
void setVehicle(@Qualifier("bike") Vehicle vehicle) {
this.vehicle = vehicle;
}
setter方法注入2
@Autowired
@Qualifier("bike")
void setVehicle(Vehicle vehicle) {
this.vehicle = vehicle;
}
属性注入
@Autowired
@Qualifier("bike")
Vehicle vehicle;
@Required
@Required 注释应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationException 异常。
@Required
void setColor(String color) {
this.color = color;
}
<bean class="com.baeldung.annotations.Bike">
<property name="color" value="green" />
</bean>
@Value
我们可以使用@Value将属性值注入bean。它与构造方法注入,setter方法注入和属性注入兼容。
构造方法注入
Engine(@Value("8") int cylinderCount) {
this.cylinderCount = cylinderCount;
}
setter方法注入
@Autowired
void setCylinderCount(@Value("8") int cylinderCount) {
this.cylinderCount = cylinderCount;
}
setter方法注入2
@Value("8")
void setCylinderCount(int cylinderCount) {
this.cylinderCount = cylinderCount;
}
属性注入
@Value("8")
int cylinderCount;
我们可以在@Value中使用占位符字符串来连接外部源中定义的值,例如,在.properties或.yaml文件中
engine.fuelType=petrol
@Value("${engine.fuelType}")
String fuelType;
即使使用SpEL,我们也可以使用@Value。有关@Value的文章中可以找到更高级的示例
@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();
}
@Lazy
- 标记在bean工厂方法:延迟方法的调用
- 标记在配置类上:所有的bean都会被延迟创建
- 标记在组件类上(不包括配置类):bean会被延迟初始化
- 标记在构造方法,setter方法,属性上:依赖项延迟加载
如需进一步阅读,请访问此文章
@Primary
有时我们需要定义多个相同类型的bean。在这些情况下,注入将不会成功,因为Spring不知道我们需要哪种bean
@Component
@Primary
class Car implements Vehicle {}
@Component
class Bike implements Vehicle {}
@Component //spring 注入Car Bean
class Driver {
@Autowired
Vehicle vehicle;
}
@Component //spring 注入bike Bean
class Biker {
@Autowired
@Qualifier("bike")
Vehicle vehicle;
}
@Scope
我们使用@Scope来定义@Component类的范围或@Bean定义。它可以是singleton,prototype,request,session,globalSession或某些自定义范围。
@Component
@Scope("prototype")
class Engine {}
Context Configuration Annotations
@Profile
详见这里
@Import
我们可以使用特定的@Configuration类,而不使用组件扫描(component scanning )。我们可以为这些类提供@ Import的value参数:
@Import(VehiclePartSupplier.class)
class VehicleFactoryConfig {}
@ImportResource
我们可以使用此批注导入XML配置。我们可以使用locations参数或其别名value参数指定XML文件位置:
@Configuration
@ImportResource("classpath:/annotations.xml")
class VehicleFactoryConfig {}
@PropertySource
指定properties文件 @PropertySource利用Java 8重复注释功能,这意味着我们可以多次使用它标记一个类:
@Configuration
@PropertySource("classpath:/annotations.properties")
@PropertySource("classpath:/vehicle-factory.properties")
class VehicleFactoryConfig {}
@PropertySources
指定多个@PropertySource配置:
@Configuration
@PropertySources({
@PropertySource("classpath:/annotations.properties"),
@PropertySource("classpath:/vehicle-factory.properties")
})
class VehicleFactoryConfig {}
Spring Boot Annotations
概述
Spring Boot通过自动配置功能使Spring更容易配置。
在这个文章中,讨论 org.springframework.boot.autoconfigure
和org.springframework.boot.autoconfigure.condition
包。
@SpringBootApplication
这个注解来标记Spring Boot应用程序的主类
@SpringBootApplication
默认包括 @Configuration
, @ EnableAutoConfiguration
和 @ComponentScan
注释。
@SpringBootApplication
class VehicleFactoryApplication {
public static void main(String[] args) {
SpringApplication.run(VehicleFactoryApplication.class, args);
}
}
@EnableAutoConfiguration
顾名思义,支持自动配置。这意味着Spring Boot在其类路径中查找自动配置bean并自动应用它们。
@Configuration
@EnableAutoConfiguration
class VehicleFactoryConfig {}
自动配置条件 Auto-Configuration Conditions
@ConditionalOnClass and @ConditionalOnMissingClass
@ConditionalOnClass
表示对应的类在classpath目录下存在时,才创建标记上该注解的类的实例
@ConditionalOnMisssingClass
表示classPath不存在指定的Class时,创建标记上该注解的类的实例
@Configuration
@ConditionalOnClass(DataSource.class)
class MySQLAutoconfiguration {
//...
}
@ConditionalOnBean and @ConditionalOnMissingBean
ConditionalOnBean: 表示指定的bean classes and/or bean names在当前容器中,才创建标记上该注解的类的实例 ConditionalOnMissingBean: 表示指定的bean classes and/or bean names不存在当前容器中,才创建标记上该注解的类的实例,有指定忽略ignored的参数存在,可以忽略Class、Type等
@Bean
@ConditionalOnBean(name = "dataSource")
LocalContainerEntityManagerFactoryBean entityManagerFactory() {
// ...
}
@ConditionalOnResource
仅在存在特定资源时才创建标记上该注解的类的实例
@ConditionalOnResource(resources = "classpath:mysql.properties")
Properties additionalProperties() {
// ...
}
@ConditionalOnWebApplication and @ConditionalOnNotWebApplication
我们可以根据当前应用程序是否是Web应用程序创建
@ConditionalOnWebApplication
HealthCheckController healthCheckController() {
// ...
}
@ConditionalExpression
当SpEL表达式求值为true时才创建
@Bean
@ConditionalOnExpression("${usemysql} && ${mysqlserver == 'local'}")
DataSource dataSource() {
// ...
}
@Conditional
对于更复杂的条件,我们可以创建一个评估自定义条件的类。我们告诉Spring使用@Conditional使用这个自定义条件
@Conditional(HibernateCondition.class)
Properties additionalProperties() {
//...
}
Spring Bean Annotations
概述
在本文中,我们将讨论用于定义不同类型bean的最常见的Spring bean注释。
有几种方法可以在Spring容器中配置bean。我们可以使用XML配置声明它们。我们可以在配置类中使用@Bean批注声明bean。
或者我们可以使用org.springframework.stereotype包中的一个注释标记该类,并将其余部分留给组件扫描。
@ComponentScan 组件扫描( Component Scanning )
如果启用了组件扫描,Spring可以自动扫描bean的包。
@ComponentScan配置要扫描具有注释配置的类的包。我们可以直接使用basePackages或value参数之一指定基本包名(value是basePackages的别名):
basePackages
@Configuration
@ComponentScan(basePackages = "com.baeldung.annotations")
class VehicleFactoryConfig {}
basePackageClasses
此外,我们可以使用basePackageClasses参数指向基础包中的类:
@Configuration
@ComponentScan(basePackageClasses = VehicleFactoryConfig.class)
class VehicleFactoryConfig {}
basePackages 多参数
参数为字符串数组指定多个包
@ComponentScan({"com.my.package.first","com.my.package.second"})
basePackages 空参数
不指定参数默认为当前包
指定多次
@ComponentScan利用Java 8重复注释功能,这意味着我们可以多次用它标记一个类
方法一
@Configuration
@ComponentScan(basePackages = "com.baeldung.annotations")
@ComponentScan(basePackageClasses = VehicleFactoryConfig.class)
class VehicleFactoryConfig {}
方法二
@Configuration
@ComponentScans({
@ComponentScan(basePackages = "com.baeldung.annotations"),
@ComponentScan(basePackageClasses = VehicleFactoryConfig.class)
})
class VehicleFactoryConfig {}
使用XML配置
<context:component-scan base-package="com.baeldung" />
@Component
@Component是类级别注释。在组件扫描期间,Spring Framework会自动检测使用@Component注释的类
@Component
class CarUtility {
// ...
}
默认情况下,此类的bean实例名称为小写首字母的类名。也可以使用 value
参数指定其他名称。
由于 @Repository
, @Service
, @Configuration
和 @Controller
都是 @Component
的元注释,因此它们共享相同的bean命名行为。此外,Spring会在组件扫描过程中自动拾取它们。
@Repository
DAO或Repository类通常表示应用程序中的数据库访问层,应使用@Repository注释:
@Repository
class VehicleRepository {
// ...
}
使用此批注的一个优点是它启用了自动持久性异常转换。
当使用诸如Hibernate之类的持久性框架时,在使用 @Repository
注释的类中抛出的本机异常将自动转换为Spring的 DataAccessExeption
的子类。
要启用异常转换,我们需要声明自己的PersistenceExceptionTranslationPostProcessor
bean
:
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
在大多数情况下,Spring会自动执行上述步骤。 或者,通过XML配置:
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
@Service
应用程序的业务逻辑通常位于服务层内 - 因此我们将使用@Service批注指示类属于该层:
@Service
public class VehicleService {
// ...
}
@Controller
@Controller是一个类级别的注释,告诉Spring Framework这个类在Spring MVC中充当控制器
@Controller
public class VehicleController {
// ...
}
@Configuration
配置类可以包含使用@Bean注释的bean定义方法:
@Configuration
class VehicleFactoryConfig {
@Bean
Engine engine() {
return new Engine();
}
}
Stereotype Annotations and AOP
当我们使用Spring构造型注释时,很容易创建一个针对具有特定构造型的所有类的切入点。
例如,假设我们想要从DAO层测量方法的执行时间。我们将利用@Repository构造型创建以下方面(使用AspectJ注释)
@Aspect
@Component
public class PerformanceAspect {
@Pointcut("within(@org.springframework.stereotype.Repository *)")
public void repositoryClassMethods() {};
@Around("repositoryClassMethods()")
public Object measureMethodExecutionTime(ProceedingJoinPoint joinPoint)
throws Throwable {
long start = System.nanoTime();
Object returnValue = joinPoint.proceed();
long end = System.nanoTime();
String methodName = joinPoint.getSignature().getName();
System.out.println(
"Execution of " + methodName + " took " +
TimeUnit.NANOSECONDS.toMillis(end - start) + " ms");
return returnValue;
}
}
在这个例子中,我们创建了一个切入点,它匹配用@Repository注释的类中的所有方法。我们使用 @Around环绕通知 然后定位该切入点并确定截获的方法调用的执行时间。
使用此方法,我们可以向每个应用程序层添加日志记录,性能管理,审计或其他行为。