项目实训 14 学习Spring(8)

274 阅读8分钟

1.9:基于注解的容器配置:

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

注解注入在 XML 注入之前执行。因此,XML配置将覆盖通过两种方法连接的属性的注解。

与往常一样,您可以将它们注册为单独的 bean 定义,但是也可以通过在基于 XML 的 Spring 配置中包含以下标记来隐式注册它们(请注意包含context名称空间)(确定注解的查找空间):

image.png

(隐式注册的后处理器包括AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessor和上述RequiredAnnotationBeanPostProcessor。)

context:annotation-config/仅在定义它的相同应用程序上下文中查找 bean 上的 注解。这意味着,如果您将context:annotation-config/放在WebApplicationContext中而不是DispatcherServlet,则它仅检查控制器中的@Autowired bean,而不检查服务。

1.9.1:@Required:

@Required注解 适用于 bean 属性设置器方法(setter)。

image.png

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

1.9.2:@Autowired:

(可以使用 JSR 330 的@Inject注解 代替 Spring 的@Autowired注解。)

您可以将@Autowired(按类型自动装配,默认行为是将带注解的方法,构造函数和字段视为指示所需的依赖项)注解 应用于构造函数,如以下示例所示:

image.png

如果目标 bean 仅定义一个构造函数作为开始,则不再需要在此类构造函数上使用@Autowired注解。但是,如果有几个构造函数可用,则必须至少注解一个,以告诉容器使用哪个构造函数。

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

image.png

表示该类bean在容器中装配时会自动找到相应的movieFinder bean调用setter方法。

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

image.png

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

image.png

您还可以通过将注解添加到需要该类型数组的字段或方法中,来提供ApplicationContext中所有特定类型的 bean:

image.png

同样适用于类型化集合:

image.png

如果希望数组或列表中的项按特定序列排序,则目标 bean 可以实现org.springframework.core.Ordered接口或使用@Order或标准@Priority注解。

您可以在目标类级别和@Bean方法上声明@Order注解,@Order值可能会影响注入点的优先级,但是要注意,它们不会影响单例启动 Sequences,这是由依赖关系和@DependsOn声明确定的正交关注点。

只要预期的密钥类型为String,即使是键入的Map实例也可以自动装配。 Map 值包含所有预期类型的 bean,并且键包含相应的 bean 名称:

image.png

默认情况下,只要有零个候选 bean 可用,自动装配就会失败。可以按照下例更改此行为,使得能够跳过该情况不进行自动装配。

image.png

每个类仅可以将一个带注解的构造函数标记为必需,但可以对多个非必需的构造函数进行@Autowired注解。在这种情况下,每个候选对象都将被考虑在内,并且 Spring 使用最贪婪的构造函数,其依赖关系可以得到满足-即具有最多参数的构造函数。

在@Autowired上使用required,required=false 属性表示自动装配不需要该属性。如果无法自动装配该属性,则将其忽略。

可以通过 Java 8 的java.util.Optional表示特定依赖项的非必需性质:

image.png

从 Spring Framework 5.0 开始,您还可以使用@Nullable注解表示其为非必需的:

image.png

您也可以将@Autowired用于众所周知的依赖项:BeanFactory,ApplicationContext,Environment,ResourceLoader,ApplicationEventPublisher和MessageSource。这些接口及其扩展接口(例如ConfigurableApplicationContext或ResourcePatternResolver)将自动解析,而无需进行特殊设置。下面的示例自动连接ApplicationContext对象:

image.png

@Autowired,@Inject,@Resource和@Value注解由 Spring BeanPostProcessor实现处理。这意味着您不能在自己的BeanPostProcessor或BeanFactoryPostProcessor类型(如果有)中应用这些 注解。必须使用 XML 或 Spring @Bean方法显式“连接”这些类型。

1.9.3:使用@Primary微调基于注解的自动装配:

由于按类型自动布线可能会导致多个候选对象,因此通常有必要对选择过程进行更多控制。实现此目的的一种方法是使用 Spring 的@Primary注解。@Primary表示当多个 bean 可以自动连接到单值依赖项的候选对象时,应优先考虑特定的 bean。如果候选中恰好存在一个primary bean,则它将成为自动装配的值。

考虑以下将firstMovieCatalog定义为主MovieCatalog的配置:

image.png

使用前面的配置,下面的MovieRecommender与firstMovieCatalog自动连接:

@Configuration 注解类表示这个类可以使用 Spring IoC 容器作为 bean 定义的来源。

image.png

1.9.4:使用限定符对基于注解的自动装配进行微调:

当您需要对选择过程进行更多控制时,可以使用 Spring 的@Qualifier注解。您可以将限定符值与特定的参数相关联,从而缩小类型匹配的范围(找限定符值与bean 限定符匹配的),以便选择特定的 bean。

image.png

image.png 您还可以在各个构造函数参数或方法参数上指定@Qualifier注解,如以下示例所示:

对于匹配,bean名称被视为默认的限定符值。因此,您可以用id或main定义 bean,而不是嵌套的限定符元素,从而得到相同的匹配结果。尽管您可以使用此约定按名称引用特定的 bean,但@Autowired基本上是关于带有可选语义限定符的类型驱动的注入。会出现一些bean的限定符设定为一样的,做不到对唯一bean id的引用。好的限定符值为main或EMEA或persistent,它们表示特定组件的特性,它们独立于 Bean id,如果是匿名 Bean 定义(即为初始化id),则可以自动生成这些组件。

如果没有其他解析度指示符(例如限定词或主标记),则对于非唯一依赖性情况,Spring 将注入点名称(即字段名称或参数名称)与目标 Bean 名称进行匹配,然后选择同名候选人(如果有)。

如果您打算按名称表示注解驱动的注入,则不要主要使用@Autowired,即使它能够在类型匹配的候选对象中按 bean 名称进行选择。而是使用 JSR-250 @Resource注解,该注解的语义定义是通过其唯一名称来标识特定目标组件,而声明的类型与匹配过程无关。

@Autowired:按类型选择候选 Bean 之后,仅在那些类型选择的候选中考虑指定的String限定符值(例如,将account限定符与标记有相同限定符标签的 Bean 匹配)。

@Autowired还考虑了自我引用以进行注入(即,引用回当前注入的 Bean)。请注意,自我注入是一个后备。对其他组件的常规依赖始终优先。

@Autowired适用于字段,构造函数和多参数方法,从而允许在参数级别缩小限定符注解的范围。相反,@Resource仅适用于具有单个参数的字段和 bean 属性设置器方法。因此,如果注入目标是构造函数或多参数方法,则应坚持使用限定符。

您可以创建自己的自定义限定符注解。定义一个注解并在定义中提供@Qualifier注解,如以下示例所示:

image.png

@Target注解表示该自定义注解能用在何处:FIELD能用在属性上;PARAMETER能用在参数上。

@Retention注解表示该自定义注解能用在何时(生命周期):RUNTIME表示程序运行时仍存在。

然后,您可以在@Autowired的字段和参数上提供自定义限定符,如以下示例所示:

image.png

接下来,您可以提供有关候选 bean 定义的信息。您可以将标记添加为标记的子元素,然后指定type和value以匹配您的自定义限定符 注解。

image.png

在某些情况下,使用没有值的注解就足够了。当注解用于更一般的用途并且可以应用于几种不同类型的依赖项时,这将很有用。首先,定义简单的 注解,如以下示例所示:

image.png

然后将注解添加到要自动装配的字段或属性,如以下示例所示:

image.png

现在,bean 定义只需要一个限定符type,如以下示例所示:

image.png

您还可以定义自定义限定符注解,除了简单的value属性之外,还可以接受命名属性。如果随后在要自动装配的字段或参数上指定了多个属性值,则 bean 定义必须与所有此类属性值匹配才能被视为自动装配候选。

image.png

要自动装配的字段将用定制限定符进行 注解,并包括两个属性genre和format的值,如以下示例所示:

image.png

最后,bean 定义应包含匹配的限定符值。此示例还演示了可以使用 bean 元属性代替元素。如果可用,则元素及其属性优先,但是如果不存在此类限定符,则自动装配机制将退回到标记内提供的值,如以下示例中的最后两个 bean 定义:

image.png