基于注解的容器配置

在配置 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. 把pyecharts动图导入到PPT中

    如何把echarts 动图导入PPT 置顶 且听风来 2019-05-22 14:54:17 3347 收藏 6展开 首先看PPT是否开启插件,开启后 此处就有标志,然后就在你想插入的幻灯片处插入两个 ...

  2. 将本地文件推送到Gitee仓库

    完整的步骤 1.在gitee中创建仓库 2.下载.安装git 3.推送文件到gitee 推送文件到gitee 1.在要上传的文件夹空白处,点击右键,选择 git bash here 2.输入 git ...

  3. Django Rest Frame work 如何使用serializers序列化

    Django Rest Frame work 如何使用serializers序列化       Django Rest Framework提供了serializers模块,用于序列化和反序列化模型实例 ...

  4. What is REST and Restful?

    什么是rest 和 restful? 提出rest的作者,目的:符合框架原理的情况下,理解和评估以网络为基础的应用软件的架构设计,得到一个功能强,性能好,适宜通讯的架构. Fielding将他对互联网 ...

  5. WPF 后台实现按数字键滚动DataGrid 当前选中项

    最近遇到个项目,设备上没有鼠标,界面为全屏的一个DataGrid,需要实现按小键盘的0和1让DataGrid的当前选中行进行上下滚动 起到重要参考的是:   https://blog.csdn.net ...

  6. mybatis获取参数值的方式

     示例: 总结:  

  7. Scrapy模块和Asyncpy模块

    Scrapy笔记 scrapy的环境安装 mac or linux: pip install scrapy windows: pip install wheel scrapy框架异步请求基于Twist ...

  8. Centos8——Nginx下载安装 & 部署项目

    Centos8--Nginx下载安装 & 部署项目 官网:http://nginx.org/ 官网下载:http://nginx.org/en/download.html 创建文件夹 ps: ...

  9. Java基础之变量与常量

    变量 定义:可以变化的量. Java是一种强类型语言,每个变量都必须声明其类型. Java变量是程序种最基本的存储单元,其要素包括变量名,变量类型和作用域. //数据类型 变量名 = 值:可以使用逗号 ...

  10. Python3之并发(五)---线程条件(Condition)和事件(Event)

    一.线程条件Condition(条件变量) 依赖锁对象(Lock,RLock),锁对象可以通过参数传入获得,或者使用自动创建的默认锁对象当多个条件变量需要共享同一个锁时,建议传入锁对象 除了带有获取到 ...