基于注解的容器配置

在配置 Spring 时,注解是否比 XML 更好?

基于注释的配置的引入提出了这种方法是否比 XML“更好”的问题。简短的回答是“视情况而定”。长答案是每种方法都有其优点和缺点,通常由开发人员决定哪种策略更适合他们。由于它们的定义方式,注释在其声明中提供了大量上下文,从而使配置更短、更简洁。然而,XML 擅长在不触及源代码或重新编译它们的情况下连接组件。一些开发人员更喜欢在源附近进行布线,而另一些开发人员则认为带注释的类不再是 POJO,此外,配置变得分散且更难控制。

无论选择如何,Spring 都可以同时适应这两种风格,甚至可以将它们混合在一起。值得指出的是,通过其JavaConfig选项,Spring 允许以非侵入性的方式使用注释,而无需触及目标组件的源代码,并且在工具方面

基于注释的配置提供了 XML 设置的替代方案,它依赖于字节码元数据来连接组件,而不是尖括号声明。开发人员不使用 XML 来描述 bean 连接,而是通过在相关类、方法或字段声明上使用注释将配置移动到组件类本身

@Required(弃用)

注释适用于 bean 属性设置方法,@Required如下例所示:

public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Required
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
} // ...
}

此注解指示必须在配置时通过 bean 定义中的显式属性值或通过自动装配来填充受影响的 bean 属性。如果受影响的 bean 属性尚未填充,则容器将引发异常。

注意:从Spring Framework 5.1 开始正式弃用@Required注释,支持使用构造函数注入进行所需设置

@Autowired

您可以将@Autowired注释应用于构造函数

public class MovieRecommender {

    private final CustomerPreferenceDao customerPreferenceDao;

    @Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
this.customerPreferenceDao = customerPreferenceDao;
} // ...
}

您还可以将@Autowired注解应用于传统的setter 方法

public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Autowired
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
} // ...
}

您还可以将注释应用于具有任意名称和多个参数的方法

您也可以应用于@Autowired字段,甚至可以将其与构造函数混合使用

public class MovieRecommender {

    private final CustomerPreferenceDao customerPreferenceDao;

    @Autowired
private MovieCatalog movieCatalog; @Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
this.customerPreferenceDao = customerPreferenceDao;
} // ...
}

默认行为是将带注释的方法和字段视为指示所需的依赖项。您可以按照以下示例所示更改此行为,使框架能够通过将其标记为非必需(即,通过将required属性设置@Autowiredfalse)来跳过不可满足的注入点

如果非必需方法的依赖项(或其依赖项之一,如果有多个参数)不可用,则根本不会调用非必需方法。在这种情况下,根本不会填充非必填字段,而保留其默认值。

您可以通过 Java 8 表达特定依赖项的非必需性质java.util.Optional,如以下示例所示:

public class SimpleMovieLister {

    @Autowired
public void setMovieFinder(Optional<MovieFinder> movieFinder) {
...
}
}

@Primary

由于按类型自动装配可能会导致多个候选者,因此通常需要对选择过程进行更多控制。

@Primary指示当多个 bean 是自动装配到单值依赖项的候选对象时,应该优先考虑特定的 bean。如果候选中恰好存在一个主 bean,则它将成为自动装配的值。

@Configuration
public class MovieConfiguration { @Bean
@Primary
public MovieCatalog firstMovieCatalog() { ... } @Bean
public MovieCatalog secondMovieCatalog() { ... } // ...
}

使用上述配置,以下MovieRecommender内容与 自动装配 firstMovieCatalog

public class MovieRecommender {

    @Autowired
private MovieCatalog movieCatalog; // ...
}

@Qualifier

@Primary当可以确定一个主要候选者时,是一种通过类型使用多个实例的自动装配的有效方法。当您需要对选择过程进行更多控制时,可以使用 Spring 的@Qualifier注解。您可以将限定符值与特定参数相关联,缩小类型匹配的范围,以便为每个参数选择特定的 bean。

public class MovieRecommender {

    @Autowired
@Qualifier("main")
private MovieCatalog movieCatalog; // ...
}

使用泛型作为自动装配限定符

您还可以使用 Java 泛型类型作为限定的隐式形式

@Configuration
public class MyConfiguration { @Bean
public StringStore stringStore() {
return new StringStore();
} @Bean
public IntegerStore integerStore() {
return new IntegerStore();
}
}

假设前面的 bean 实现了一个泛型接口,(即Store<String>Store<Integer>),您可以@AutowireStore接口和泛型用作限定符,如以下示例所示:

@Autowired
private Store<String> s1; // <String> qualifier, injects the stringStore bean @Autowired
private Store<Integer> s2; // <Integer> qualifier, injects the integerStore bean

@Resource

@Resource采用名称属性。默认情况下,Spring 将该值解释为要注入的 bean 名称。

public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Resource(name="myMovieFinder")
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}

如果没有明确指定名称,则默认名称派生自字段名称或 setter 方法。如果是字段,则采用字段名称。对于 setter 方法,它采用 bean 属性名称。

在没有指定显式名称的排他性@Resource使用情况下,类似于@Autowired,则自动按byName方式进行查找。如果没有找到符合的bean,则回退为一个原始类型进行查找,如果找到就注入。

@Value

@Value 通常用于注入外部属性:

@Component
public class MovieRecommender { private final String catalog; public MovieRecommender(@Value("${catalog.name}") String catalog) {
this.catalog = catalog;
}
}
@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig { }

以及以下application.properties文件:

catalog.name=MovieCatalog

在这种情况下,catalog参数和字段将等于该MovieCatalog值。

原理:Spring 提供了一个默认的宽松嵌入式值解析器。它将尝试解析属性值,如果无法解析,属性名称(例如${catalog.name})将作为值注入。如果要严格控制不存在的值,则应声明一个PropertySourcesPlaceholderConfigurer

@Configuration
public class AppConfig { @Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}

${} 如果无法解析任何占位符,使用上述配置可确保 Spring 初始化失败。

Spring 提供的内置转换器支持允许自动处理简单的类型转换。

Spring在后台BeanPostProcessor处理将值转换为目标类型的过程。如果您想为您自己的自定义类型提供转换支持,您可以提供您自己的 bean 实例

@Configuration
public class AppConfig { @Bean
public ConversionService conversionService() {
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
conversionService.addConverter(new MyCustomConverter());
return conversionService;
}
}

使用@PostConstruct@PreDestroy

生命周期
public class CachingMovieLister {

@PostConstruct
public void populateMovieCache() {
// populates the movie cache upon initialization...
} @PreDestroy
public void clearMovieCache() {
// clears the movie cache upon destruction...
}

}

Spring系列之基于注解的容器配置7的更多相关文章

  1. Spring IOC之基于注解的容器配置

    Spring配置中注解比XML更好吗?基于注解的配置的介绍提出的问题是否这种途径比XML更好.简单来说就是视情况而定. 长一点的答案是每一种方法都有自己的长处也不足,而且这个通常取决于开发者决定哪一种 ...

  2. Spring5参考指南:基于注解的容器配置

    文章目录 @Required @Autowired @primary @Qualifier 泛型 @Resource @PostConstruct和@PreDestroy Spring的容器配置可以有 ...

  3. 8 -- 深入使用Spring -- 4...5 AOP代理:基于注解的“零配置”方式

    8.4.5 基于注解的“零配置”方式 AspectJ允许使用注解定义切面.切入点和增强处理,而Spring框架则可识别并根据这些注解来生成AOP代理.Spring只是使用了和AspectJ 5 一样的 ...

  4. 10 Spring框架--基于注解的IOC配置

    1.工程环境搭建 2.基于注解的IOC配置 IOC注解的分类 (1)用于创建对象的 他们的作用就和在XML配置文件中编写一个<bean>标签实现的功能是一样的@Component: 作用: ...

  5. spring-第十七篇之spring AOP基于注解的零配置方式

    1.基于注解的零配置方式 Aspect允许使用注解定义切面.切入点和增强处理,spring框架可以识别并根据这些注解来生成AOP代理.spring只是用了和AspectJ 5一样的注解,但并没有使用A ...

  6. 使用 Spring 2.5 基于注解驱动的 Spring MVC

    http://www.ibm.com/developerworks/cn/java/j-lo-spring25-mvc/ 概述 继 Spring 2.0 对 Spring MVC 进行重大升级后,Sp ...

  7. 使用 Spring 2.5 基于注解驱动的 Spring MVC--转

    概述 继 Spring 2.0 对 Spring MVC 进行重大升级后,Spring 2.5 又为 Spring MVC 引入了注解驱动功能.现在你无须让 Controller 继承任何接口,无需在 ...

  8. 基于注解的形式配置Bean

    基于注解的方式配置Bean:也就说我们在每个Bean的类名前面注解一下,Spring会自动帮我们扫描Bean放进IOC容器中 I基于注解的方式配置Bean(没有依赖关系的Bean)有两个步骤: 1组件 ...

  9. Struts2基于注解的Action配置

    使用注解来配置Action的最大好处就是可以实现零配置,但是事务都是有利有弊的,使用方便,维护起来就没那么方便了. 要使用注解方式,我们必须添加一个额外包:struts2-convention-plu ...

  10. 缓存初解(五)---SpringMVC基于注解的缓存配置--web应用实例

    之前为大家介绍了如何使用spring注解来进行缓存配置 (EHCache 和 OSCache)的简单的例子,详见 Spring基于注解的缓存配置--EHCache AND OSCache 现在介绍一下 ...

随机推荐

  1. linux内核中根据函数指针追踪调用函数名

    2 linux内核中根据函数指针追踪调用函数名 linux内核的printks可以输出函数指针对应的函数名. printk("func: %pF at address: %p\n" ...

  2. 批量检测URL中的关键词,并且将不含有关键词的URL输出到txt文件当中

    编写代码时遇到的问题 写入txt(一开始忘记了tuple类型需要转换为str) 处理逻辑(一开始并没有将 body与url绑定到一起,所以或返回所有的url) 关闭太早(这点是有点疑惑的,难道不用关闭 ...

  3. 斐讯K2_V22.6.507.43降级+刷机整个过程

    K2刷机整个过程 (包括降级) 开始之前请先下载好相对应的工具包,其中包括: 官方固件:"K2_V22.6.506.28.bin"."K2_V22.6.507.43.bi ...

  4. PyQt5弹框定时关闭(python)

    PyQt5使用QMessageBox,可以设置在几秒后关闭  (作者使用的python3) info_box = QMessageBox()# 因为没使用这种方式 QMessageBox.inform ...

  5. 《Python 3网络爬虫实战》示例源码免费下载

    #好书推荐##好书奇遇季#<Python 3网络爬虫实战>京东当当天猫都有发售. https://item.jd.com/12936936.html 本书配套示例源码,文后提供了下载二维码 ...

  6. FileStream与StreamReader区别

    FileStream操作字节,更适合大文件. StreamReader操作字符,更适合小文件

  7. k8s入门_RC、RS、Deployment

    RC 什么是RC: Replication Controller(副本控制器),RC能够保证pod在任意时间运行的副本数量,能够保证pod总是可用的. RC控制的pod的多个副本,每个副本都有独立的i ...

  8. mybatis-属性名和查询字段名不相同的解决方案

    1.使用别名 resultType可以将查询结果直接映射为实体bean对象的条件是,sql查询的字段名和实体bean的属性名一致,通过反射机制完成对象的创建. select tid id,tname ...

  9. Go实现KMP和Sunday算法

    KMP 1 func KMP(str, substr string) int { 2 if substr == "" { 3 return 0 4 } 5 strLen := le ...

  10. 互联网公司IT系统架构进化之路

    一日,与一高手在茶馆聊天.他问道:在鞋厂剑派这两年,可习的什么高深的剑法?我不由一愣,细细想来,这两年每日练习的都是简单的劈砍动作和一些简练的套路.并没有去练什么高深的剑法.不过鞋厂剑派在江湖上也算小 ...