Spring自从2.0引入注解的方式取代XML配置的方式来做IOC之后,对Spring一些常用注解的含义行为一直处于比较模糊的状态,写几篇总结下Spring常用的注解。本篇包含的注解有如下几个:
- Autowired
- Resource
- Component
- Service
- Controller
- Transactional
根据它们的功能、目的,可以分为三组,Autowired和Resource是一组;Component、Service和Controller是一组;Transactional是一组
Autowired注解
Autowired顾名思义,表示自动注入,如下是Autowired注解的源代码:
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Autowired { /** * Declares whether the annotated dependency is required. * <p>Defaults to {@code true}. */ boolean required() default true; }
从Autowired的实现可以看到,Autowired可以用于类的构造方法,类的字段,类的方法以及注解类型上,但是Autowired不能用于类上面。
至此,关于Autowired注解,有如下问题需要解决:
- Autowired作用在不同的范围上(构造方法,字段、方法)上,它的装配策略如何,按名称?按类型?
- 为构造方法,字段和方法添加Autowired注解之后,谁来解析这个Autowired注解,完成装配
- 装配的bean从何处而来,是在Spring的xml文件中定义的bean吗?
从Autowired的javadoc开始
从Autowired的javadoc中得到如下信息
- AutowiredAnnotationBeanPostProcessor负责扫描Autowired注解,然后完成自动注入
- 可以对私有的字段使用Autowired进行自动装配,而无需为私有字段定义getter/setter来read/write这个字段
- 使用Autowired注解的类方法,可以是任意的方法名,任意的参数,Spring会从容器中找到合适的bean进行装配,setter自动注入跟对字段自动注入效果一样
Autowired注解的解析
当项目中使用了Autowired注解时,需要明确的告诉Spring,配置中引用了自动注入的功能,在Spring的配置文件,做法有两种
- 配置AutowiredAnnotationBeanPostProcessor
- 使用<context:annotation-config/>。<context:annotationconfig/> 将隐式地向 Spring 容器注册
AutowiredAnnotationBeanPostProcessor
、CommonAnnotationBeanPostProcessor
、PersistenceAnnotationBeanPostProcessor
以及equiredAnnotationBeanPostProcessor
这 4 个 BeanPostProcessor。
实例
1. 实例一:
-
UserSerice依赖的UserDao使用Autowired注解,
-
UserDao没有在Spring配置文件中定义
结果:UserDao为null
2. 实例二:
-
UserSerice依赖的UserDao使用Autowired注解
-
UserDao在Spring配置文件中有定义
结果:UserDao为null
3. 实例三:
-
UserSerice依赖的UserDao使用Autowired注解
-
UserDao在Spring配置文件中有定义
- Spring中使用<context:annotation-config/>
结果:UserDao正确注入,在Spring中配置的UserDao的实现,而在UserService中的是UserDao的接口,也就是说,虽然它们类型没有完全匹配,但是由于是实现
关系,Spring仍然能够完成自动注入
4. 实例四:
-
UserSerice依赖的UserDao使用Autowired注解
-
UserDao在Spring配置文件中有定义
- Spring中配置AutowiredAnnotationBeanPostProcessor
结果:UserDao正确注入,同实例三
5. 实例五:
-
UserSerice依赖的UserDao使用Autowired注解
-
UserDao在Spring配置文件中有两份定义(id不同)
- Spring中使用<context:annotation-config/>
结果:
1. 如果UserDao的属性名与某个bean的id相同,那么按照属性名和id名称匹配原则,自动装配
2. 如果UserService中定义的UserDao的属性名,与Spring配置文件中的两个id都不同,那么注入失败,异常抛出,提示,无法完整自动装配
结论:
1. 使用Autowired自动装配,必须在Spring的配置文件中使用<context:annotation-config/>来告诉Spring需要进行自动装配扫描(AutowiredAnnotationBeanPostProcessor不推荐使用)
2. Autowired默认按类型进行匹配,当匹配到多个满足条件的bean时,再按照属性名和bean的id进行匹配,如果仍然有多个匹配上或者没有一个匹配上,则抛出异常,提示自动装配失败
3. 在使用Autowired时,可以使用Qualifier注解,显式的指定,当冲突发生时,使用那个id对应的bean
@Autowired @Qualifier(value="userDao2")//冲突发生时,匹配id为userDao2的bean private IUserDao userDaoX;//Spring配置文件中定义了多个UserDao实例,但是没有一个id为userDaoX,但是确实有一个id为userDao2的bean
4. Autowired注解自动装配功能完成的是依赖的自动注入,因此,在一个bean中,它依赖的bean可以通过自动注入的方式完成而不需要显式的为它的属性进行注入。但是这些依赖的bean仍然不能省略,还是要在Spring中进行配置,省略的仅仅是bean属性的注入配置代码
Resource注解
Resource注解在功能和目的上,等效于Autowried+Qualifier注解,Resource注解是JSR-250规范的一部分,它定义在JDK的javax.annoation包中,如下是它的定义:
/* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ package javax.annotation; import java.lang.annotation.*; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.*; /** * The Resource annotation marks a resource that is needed * by the application. This annotation may be applied to an * application component class, or to fields or methods of the * component class. When the annotation is applied to a * field or method, the container will inject an instance * of the requested resource into the application component * when the component is initialized. If the annotation is * applied to the component class, the annotation declares a * resource that the application will look up at runtime. <p> * * Even though this annotation is not marked Inherited, deployment * tools are required to examine all superclasses of any component * class to discover all uses of this annotation in all superclasses. * All such annotation instances specify resources that are needed * by the application component. Note that this annotation may * appear on private fields and methods of superclasses; the container * is required to perform injection in these cases as well. * * @since Common Annotations 1.0 */ @Target({TYPE, FIELD, METHOD}) @Retention(RUNTIME) public @interface Resource { /** * The JNDI name of the resource. For field annotations, * the default is the field name. For method annotations, * the default is the JavaBeans property name corresponding * to the method. For class annotations, there is no default * and this must be specified. */ String name() default ""; /** * The name of the resource that the reference points to. It can * link to any compatible resource using the global JNDI names. * * @since Common Annotations 1.1 */ String lookup() default ""; /** * The Java type of the resource. For field annotations, * the default is the type of the field. For method annotations, * the default is the type of the JavaBeans property. * For class annotations, there is no default and this must be * specified. */ Class type() default java.lang.Object.class; /** * The two possible authentication types for a resource. */ enum AuthenticationType { CONTAINER, APPLICATION } /** * The authentication type to use for this resource. * This may be specified for resources representing a * connection factory of any supported type, and must * not be specified for resources of other types. */ AuthenticationType authenticationType() default AuthenticationType.CONTAINER; /** * Indicates whether this resource can be shared between * this component and other components. * This may be specified for resources representing a * connection factory of any supported type, and must * not be specified for resources of other types. */ boolean shareable() default true; /** * A product specific name that this resource should be mapped to. * The name of this resource, as defined by the <code>name</code> * element or defaulted, is a name that is local to the application * component using the resource. (It's a name in the JNDI * <code>java:comp/env</code> namespace.) Many application servers * provide a way to map these local names to names of resources * known to the application server. This mapped name is often a * <i>global</i> JNDI name, but may be a name of any form. <p> * * Application servers are not required to support any particular * form or type of mapped name, nor the ability to use mapped names. * The mapped name is product-dependent and often installation-dependent. * No use of a mapped name is portable. */ String mappedName() default ""; /** * Description of this resource. The description is expected * to be in the default language of the system on which the * application is deployed. The description can be presented * to the Deployer to help in choosing the correct resource. */ String description() default ""; }
Autowried注解,首先根据类型匹配,如果类型匹配到多个,那么在根据属性名和bean的id进行匹配(可以由Qualifier注解强制匹配指定的bean id)。Resource注解则顺序不同,它有如下几种可能的情况:
- Resource注解指定了name属性和type属性
策略:首先进行按名称匹配策略: 匹配name属性和bean的id,如果匹配,则判断查找到的bean是否是type属性指定的类型,如果是type属性指定的类型,则匹配成功。如果不是type属性指定的类型,则抛出异常,提示匹配失败;如果name属性跟bean的id不匹配,则抛出异常提示没有bean的id匹配name属性
- Resource注解指定了name属性,未指定type属性
策略:查找bean的id为name属性的bean,查找到,不关心类型为什么,都是匹配成功;如果找不到name属性指定的bean id,则匹配失败,抛出异常
- Resource注解指定了type属性,未指定name属性
策略:首先进行按名称匹配策略: 匹配属性名和bean的id,如果匹配,则判断查找到的bean是否是type属性指定的类型,如果是type属性指定的类型,则匹配成功。如果不是type属性指定的类型,则抛出异常,提示匹配失败;其次进行按类型匹配策略: 如果属性名跟bean的id不匹配,则查找类型为type的bean,如果仅仅找到一个,自动装配成功,其它情况失败。
- Resource注解未指定type属性和name属性
策略:首先进行按属性名匹配策略,匹配则注入成功;如果属性名不匹配,则进行类型匹配策略,只有为一个类型匹配才成功,其他情况都失败
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <context:annotation-config/> <!--UserDao和UserDao2都实现了IUserDao接口--> <bean id="userDao2" class="com.tom.user.dao.UserDao2"></bean> <bean id="userDao" class="com.tom.user.dao.UserDao"></bean> <!--UserService依赖IUserDao实例--> <bean id="userService" class="com.tom.user.service.UserService"></bean> </beans>
相关推荐
在Spring框架中,`@Autowired`和`@Resource`注解是两个常见的依赖注入(DI, Dependency Injection)工具,它们都是用来解决组件之间的耦合问题,使得代码更加灵活和可测试。然而,这两个注解在具体使用时有一些关键性...
在Spring框架中,注解是实现依赖注入的重要方式,其中包括`@Autowired`和`@Resource`两个常用的注解。它们虽然都可以用来注入依赖,但在实际使用中存在一些区别。 首先,`@Autowired`注解是Spring框架特有的,主要...
Spring注解详解 -- @Autowired、@Resource和@Service Spring框架中有三个非常重要的注解,即@Autowired、@Resource和@Service。这三个注解都是Spring框架中最常用的注解,它们都是用于解决Spring框架中的依赖注入...
Spring 框架中提供了两个重要的注解,分别是@Resource 和@Autowired,它们都是用于 bean 的自动装配的。了解这两个注解的区别和使用场景是非常重要的。 首先,@Autowired 是 Spring 提供的注解,需要导入 org....
在Java开发领域,Spring框架是应用最广泛的IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)框架之一。Spring的核心特性之一是使用注解来简化配置,其中`@Autowired`和`@...
Spring 3.x 框架引入了依赖注入的注解,改变了传统的 XML 配置方式,提供了一种更加灵活和方便的依赖配置方式。下面对 Spring 3.x 的注解应用进行详细的介绍。 一、属性装配 在 Spring 3.x 中,提供了两种用于...
以下是一些常用的Spring注解: 1. **@Component** - 用于标记一个类作为Spring管理的Bean。 - 可以配合@ComponentScan注解使用,自动扫描指定包下的所有组件。 2. **@Service** - 特别适用于业务逻辑层的服务...
"springtest3"通常代表一个或多个Java源代码文件,这些文件包含使用Spring注解的类。例如,可能会有一个`@Component`注解的类表示一个Spring Bean,或者一个`@Service`、`@Repository`或`@Controller`注解的类,...
在Spring框架中,`@Resource`和`@Component`是两个重要的注解,它们用于不同的目的,但都与依赖注入(Dependency Injection,简称DI)息息相关。理解这两个注解的使用和区别是掌握Spring框架核心概念的关键。 首先...
在Spring框架中,`@Resource`和`@Component`是两个非常重要的注解,它们用于不同的目的,但都与依赖注入(Dependency Injection, DI)息息相关。这篇文章将深入探讨这两个注解,以及它们如何在Spring应用中协同工作...
在Spring框架中,`@Autowired`和`@Resource`都是用于自动装配Bean的重要注解,它们简化了依赖注入的过程,使得代码更加简洁、易于维护。本文将深入探讨这两个注解的使用、区别以及如何在实际开发中应用它们。 首先...
依赖注入是Spring框架的核心特性之一,它通过反转对象创建和管理的控制权,使得应用程序组件之间的耦合度降低。在Spring中,通常通过以下三种注解实现IoC: - `@Autowired`:自动装配,Spring会根据类型或名称找到...
在Spring框架中,`@Autowired`注解是一个关键特性,用于简化依赖注入的过程。依赖注入是一种设计模式,它允许我们解耦代码,提高模块的可测试性和可维护性。在这个主题中,我们将深入探讨`@Autowired`的工作原理、...
本文将详细介绍几个关键的注解,包括 @Autowired、@Qualifier、@Resource 和 @PostConstruct,以及它们在实际开发中的应用。 ## 1. @Autowired 注解 @Autowired 是 Spring 提供的一种自动装配机制,它可以根据类型...
`@Autowired`是Spring中最常用的注解之一,用于自动装配Bean。它默认按照类型进行匹配,即`byType`,这意味着Spring会寻找与注解类型相匹配的唯一Bean,并将其注入。如果存在多个相同类型的Bean,则可以通过`@...
总结来说,Spring注解提供了声明和注册Bean的简洁方式,通过这些注解,我们能够方便地进行依赖注入和组件扫描,极大地简化了Spring应用的配置工作。同时,理解每个注解背后的原理及使用场景对于开发高效且可维护的...
Spring常用注解(收藏大全) Spring 框架中提供了许多注解,以便于开发者快速、方便地开发应用程序。这些注解可以分为多个类别,包括 bean 声明、依赖注入、配置类相关、切面相关、属性支持、值注入、环境切换等。 ...
在这个"spring使用resource注解的demo"中,我们将深入探讨如何使用`@Resource`以及它与`@Autowired`的区别。 首先,`@Resource`注解的主要目的是为了自动装配bean,它的基本语法是在字段或方法上使用,如: ```...
使用Spring注解进行依赖注入,如`@Autowired`和`@Resource`,不仅简化了代码结构,减少了XML配置文件的冗余,还增强了代码的可读性和灵活性。通过合理利用这些注解及其辅助注解如`@Qualifier`,开发者可以更高效地...
首先,Spring框架的核心特性之一就是依赖注入(Dependency Injection,简称DI),它允许开发者将对象之间的依赖关系从代码中解耦,提高了代码的可测试性和可维护性。在Spring中,注解是实现依赖注入的主要方式,如`@...