`
bit1129
  • 浏览: 1052424 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【Spring框架一】Spring常用注解之Autowired和Resource注解

 
阅读更多

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 容器注册 AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessorPersistenceAnnotationBeanPostProcessor 以及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注解的区别

    NULL 博文链接:https://forestqqqq.iteye.com/blog/2235292

    Spring框架中 @Autowired 和 @Resource 注解的区别

    Spring框架中 @Autowired 和 @Resource 注解的区别 在 spring 框架中,除了使用其特有的注解外,使用基于 JSR-250 的注解,它包括 @PostConstruct, @PreDestroy 和 @Resource 注释。  首先,咱们简单了解 @...

    Spring注解@Resource和@Autowired.doc

    Spring注解@Resource和@Autowired.doc

    SpringBoot常用注解详解含使用示例(值得珍藏)

    本文将详细介绍Spring Boot中最常用的注解,包括@SpringBootApplication、@Component、@Service、@Repository、@Controller、@RequestMapping、@GetMapping、@PostMapping、@PutMapping、@DeleteMapping、@Autowired...

    详解Spring注解--@Autowired、@Resource和@Service

    本篇文章主要介绍最重要的三个Spring注解,也就是@Autowired、@Resource和@Service,具有很好的参考价值。下面跟着小编一起来看下吧

    Spring注解@Resource和@Autowired区别对比详解

    主要介绍了Spring注解@Resource和@Autowired区别对比详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    Spring Boot最常用的30个注解.docx

    详细介绍了Spring Boot最常用的30个注解,包含概念、原理、示例 Spring Boot最常用的30个注解 一、 @SpringBootApplication 二、 Spring Bean 相关 1 @Controller 2 @Service 3 @Repository 4 @Component 5 @Bean 6 ...

    25个经典的Spring面试问答

    什么是Spring框架Spring框架有哪些主要模块 使用Spring框架能带来哪些好处 什么是控制反转IOC什么是依赖注入 请解释下Spring框架中的IoC BeanFactory和ApplicationContext有什么区别 Spring有几种配置方式 如何用...

    Spring注解 - 52注解 - 原稿笔记

    注解包含: 拦截器 , 过滤器 , 序列化 , @After , @AfterReturning , @AfterThrowing , @annotation , @Around , @Aspect , @Autowired , @Bean , @Before , @Component , @ComponentScan , @ComponentScans , @...

    springMVC-annotation注解介绍

    @Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource,需要导入,但是Spring支持该注解的注入。 1、共同点 两者都可以写在字段和setter方法上。两者...

    Spring面试专题.pdf

    1、什么是 Spring 框架?Spring 框架有哪些主要模块? 2、使用 Spring 框架能带来哪些好处? 3、什么是控制反转(IOC)?什么是依赖注入? 4、请解释下 Spring 框架中的 IoC? 5、BeanFactory 和 ApplicationContext ...

    Spring面试题.zip

    1、什么是 Spring 框架?Spring 框架有哪些主要模块? 2、使用 Spring 框架能带来哪些好处? 3、什么是控制反转(IOC)?什么是依赖注入? 4、请解释下 Spring 框架中的 IoC? 5、BeanFactory 和 ApplicationContext ...

    基于注解的DI.docx

    常用注解: @Component、创建对象 ...@Autowired、spring框架中引用类型赋值的注解,支持byName、byType,默认byType @Resource、jdk中的注解,使用自动注入给引用数据类型赋值,支持byName、byType,默认byName

    高级开发spring面试题和答案.pdf

    Spring下描述依赖关系@Resource, @Autowired和@Inject的区别与联系 Spring中BeanFactory和ApplicationContext的区别 谈谈Spring IOC的理解,原理与实现? bean的生命周期,详细看上面 SpringBoot自动装配的过程的原理...

    Spring的学习笔记

    一、 开始使用annotation配置Spring 16 二、 @Autowired、@Qualifier 16 (一) @Autowired 16 (二) @Qualifier 17 三、 @Resource(重要、推荐) 17 (一) JSR-250 17 (二) @Resource 17 四、 @Componet 18 五、 @Scope...

    spring.doc

    不用spring异常通知,另一种处理异常 96 4.2.2.2Aop注解形式(了解) 99 注解注入拓展: 103 5 Spring数据库 106 5.1 Spring+JDBC 106 5.1.1 Jdbc编程特点 106 5.1.2引入DataSource 106 5.1.3 核心类JdbcTemplate ...

    springboot学习思维笔记.xmind

    @Autowired:Spring提供的注解 @Inject:JSR-330提供的注解 @Resource:JSR-250提供的注解 Java配置 @Configuration声明当前类是一个配置类 @Bean注解在方法上,声明当前方法的返回值为一个...

    Spring中文帮助文档

    8.3.5. 常用注解 8.3.6. JUnit 3.8遗留支持 8.3.7. Spring TestContext Framework 8.3.8. PetClinic示例 8.4. 更多资源 II. 中间层数据访问 9. 事务管理 9.1. 简介 9.2. 动机 9.3. 关键抽象 9.4. 使用资源...

    Spring API

    8.3.5. 常用注解 8.3.6. JUnit 3.8遗留支持 8.3.7. Spring TestContext Framework 8.3.8. PetClinic示例 8.4. 更多资源 II. 中间层数据访问 9. 事务管理 9.1. 简介 9.2. 动机 9.3. 关键抽象 9.4. 使用资源...

Global site tag (gtag.js) - Google Analytics