16 使用注解进行bean定义

除了在Spring配置文件中通过bean元素定义一个bean外。我们还可以通过在Class上使用特定的注解进行标注,然后让Spring去扫描这些特定的注解,并把它们当做一个bean进行定义。

16.1 @Component

@Component是Spring中用来定义bean最基本的注解,通过在Class类上标注对应的注解就可以让Spring扫描到对应的定义,并把其作为一个bean定义到对应的bean容器中。

@Component
public class Hello {}

当Spring扫描到这样一个使用@Component进行标注的类时,默认会定义一个beanName为我们的类名的bean,对应首字母小写。所以在上述示例中默认就会生成一个类型为Hello,beanName为“hello”的bean。当然我们也可以通过@Component的value属性来指定需要生成的bean的beanName。如下示例中就通过value属性指定了对应生成的bean的beanName为“abc”。

@Component("abc")
public class Hello {}

除了@Component外,Spring默认还支持对@Controller、@Service和@Repository注解的扫描。它们可以用来标注在特定bean上,如通常会将@Controller标注在Controller层的类上,将@Service标注在Service层的类上,然后将@Repository标注在Dao层的类上。这些都只是不成文的规定而已,如果用户愿意,我们也可以在Service层上使用@Controller、@Component等进行标注,Spring在扫描到之后都会将它们以对应的bean进行定义。之所以有这么几种不同的注解可以用来定义bean,其中一个主要的原因是我们可以通过不同的注解来区分不同的bean类型,然后可以让Spring在进行扫描的时候只扫描特定类型的注解。当我们使用SpringMVC时,我们常会让SpringMVC对应的ApplicationContext只扫描@Controller,然后让传统的ApplicationContext只扫描除@Controller以外的其它类型的注解,用以将不同类型的bean定义在不同的bean容器中,这样某些针对特定bean容器中的操作就只会针对某些bean产生作用。@Controller、@Service和@Repository也可以通过value属性来指定对应需要生成的bean定义的beanName,默认都是当前Class类名的首字母小写后的结果。

16.2 定义自己的@Component

我们也可以通过@Component定义自己的注解,即在自己的注解上使用@Component进行标注,这样当我们使用自定义的注解标注在Class上时,Spring默认也会将其作为一个bean进行定义。如下我们定义了一个@MyComponent,然后在其上面使用@Component进行了标注,当然这里使用@Controller、@Service和@Repository等进行标注也是可以的,实际上它们的定义也都是使用@Component进行了标注的。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Component
public @interface MyComponent {public String value() default "";}

之后我们可以在Class上使用@MyComponent进行标注,Spring在进行扫描时默认也会将它们作为一个bean进行定义。

@MyComponent("abc")
public class Hello {}

其实,我们还可以让Spring扫描自定义的注解,让其将标注了自定义注解的Class定义为对应的bean,而我们的自定义注解可以不必使用@Component等原始就支持的注解进行标记。当然,这种用法也是需要进行些许配置的,主要就是告诉Spring需要扫描哪些注解,这部分内容将在后续讲解扫描时的过滤器时进行讲解。

16.3 设置扫描类路径

其实光使用@Component等标注在Class上还不足以使Spring进行扫描并将它们作为一个bean进行定义。我们必须通过配置来告诉Spring进行扫描的类路径。首先我们必须在Spring的配置文件中引入context命名空间,然后通过<context:component-scan/>标签定义启用Spring扫描@Component等注解的功能。<context:component-scan/>标签有一个必须指定的属性,base-package,其是用来指定我们需要进行扫描的基本包路径的,指定后Spring将扫描base-package指定的包及其子孙包。如果需要指定多个基础包,则可以通过逗号进行分隔。如下示例,则表示Spring将扫描类路径下com.app.service包及其子孙包,以及com.app.dao包及其子孙包下的所有类以寻找使用@Component等注解进行标注的Class定义为对应的bean。

<?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:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="com.app.service,com.app.dao" />    </beans>

定义了<context:component-scan/>标签后,Spring默认将隐式的启用对注解的支持,即之前介绍的@Autowired等注解的使用,所以使用了该标签以后我们没必要再在Spring配置文件中显式的定义<context:annotation-config/>了。这可以通过annotation-config属性进行定义,默认是true,改成false就可以禁用自动启用对注解支持。

<context:component-scan base-package="com.app" annotation-config="true"/>    

除了必须指定的属性base-package之外,<context:component-scan/>还可以指定如下属性。

  • resource-pattern:表示可以被自动检测的Class的形式,默认为“**/*.class”,即所有的class文件。这个只是用来告诉Spring需要对哪些文件进行扫描,而并不是把它们自动定义为对应的bean。这个需要与后续需要介绍的filter区分开。
  • use-default-filters:表示使用使用默认的filter,。<context:component-scan/>将把哪些Class自动注册到bean容器是由对应的filter来控制的。该属性的值默认为true,即默认会使用默认的filter。而默认的filter会将标注了@Component、@Controller、@Service和@Repository的类,包括这四个注解所标注的注解所标注的类,都会将它们自动注册到bean容器中。
  • annotation-config:是否启用对注解的支持,即隐式的启用<context:annotation-config/>,默认为true。
  • name-generator:默认的beanName生成器,即在没有显式的指定beanName时,自动注册的bean将如何使用默认的beanName。默认将使用Class的简称,即不包含包名的类名称,并将首字母小写作为当前bean的名称。用户可以通过实现org.springframework.beans.factory.support.BeanNameGenerator接口并指定其为当前的name-generator来改变对应的策略。
  • scope-resolver:指定用于解析bean定义的scope的ScopeMetadataResolver,默认将通过AnnotationScopeMetadataResolver进行解析,而该解析器将根据类上标注的@Scope注解来解析对应的scope。默认没有指定@Scope的都是单例。
  • scoped-proxy:表示是否需要为自动检测到的需要加入bean容器中的bean生成对应的代理。默认是不生成。可选值有“no”、“interfaces”和“targetClass”,分别对应不生成、根据接口生成和根据目标class生成。这对需要使用代理的scope是非常有必须要的,如request、session等。更详细的内容请参考先前专门介绍scope的那篇文章。

16.4 使用@Scope指定scope

Spring在通过<context:component-scan/>自动检测需要添加到bean容器中的bean定义时,默认会将检测到的类单例形式添加到bean容器。如果用户希望使用其它类型的scope,则可以通过在类定义上使用@Scope进行指定。具体的scope是由@Scope的value属性进行指定的,默认是单例。如下是一个通过@Scope指定对应bean的scope为prototype的示例,即是多例形式,每次从bean容器中请求时都会获取一个全新的bean对象。

@Component
@Scope("prototype")
public class Hello {}

此外,我们还可以通过@Scope的proxyMode属性指定当前bean的代理模式。其对应ScopedProxyMode类型的枚举,可选值有DEFAULT、NO、INTERFACES和TARGET_CLASS,默认是不代理。DEFAULT的作用等同于NO。

@Component
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class Hello {}

Spring(16)——使用注解进行bean定义相关推荐

  1. 零配置 之 Spring注解实现Bean定义

    转载自  零配置 之 12.3 注解实现Bean定义 --跟我学spring3 12.3  注解实现Bean定义 12.3.1  概述 前边介绍的Bean定义全是基于XML方式定义配置元数据,且在[1 ...

  2. 我该如何学习spring源码以及解析bean定义的注册

    如何学习spring源码 前言 本文属于spring源码解析的系列文章之一,文章主要是介绍如何学习spring的源码,希望能够最大限度的帮助到有需要的人.文章总体难度不大,但比较繁重,学习时一定要耐住 ...

  3. Spring之使用注解实例化Bean并注入属性

    1.准备工作 (1)导入jar包 除了上篇文章使用到的基本jar包外,还得加入aop的jar包,所有jar包如下 所需jar包 (2)配置xml <?xml version="1.0& ...

  4. Java Spring Beans.xml里的Bean定义是如何被解析出来的

    ClassPathXmlApplicationContext的构造函数里,一部分逻辑是给各个成员变量赋上初始值: 然后是执行refresh操作. 获取ConfigurableListableBeanF ...

  5. 编码实现Spring 利用@Resource注解实现bean的注入,xml实现基本数据类型的注入

    首先分析. 1: 肯定要利用dom4j读取xml配置文件,将所有的bean的配置信息读取出来 2: 利用反射技术,实例化所有的bean 3: 写注解处理器, 利用注解和内省实现依赖对象的注入. 4: ...

  6. (转)Spring对注解(Annotation)处理源码分析1——扫描和读取Bean定义

    1.从Spring2.0以后的版本中,Spring也引入了基于注解(Annotation)方式的配置,注解(Annotation)是JDK1.5中引入的一个新特性,用于简化Bean的配置,某些场合可以 ...

  7. 品Spring:bean定义上梁山

    技术不枯燥,先来点闲聊 先说点好事高兴一下.前段时间看新闻说,我国正式的空间站建设已在进行当中.下半年,长征五号B运载火箭将在海南文昌航天发射场择机将空间站核心舱发射升空.预计用2到3年将空间站建好. ...

  8. Spring Boot-2-核心注解

    1. 核心注解 在一个标准的java应用程序的入口处(main),我们需要核心注解.@SpringBootApplication 它是一个组合注解,包含以下注解 @springBootApplicat ...

  9. 【spring容器启动】之bean的实例化和初始化(文末附:spring循环依赖原理)

    本次我们通过源码介绍ApplicationContext容器初始化流程,主要介绍容器内bean的实例化和初始化过程.ApplicationContext是Spring推出的先进Ioc容器,它继承了旧版 ...

  10. Spring源码分析:Bean加载流程概览及配置文件读取

    很多朋友可能想看Spring源码,但是不知道应当如何入手去看,这个可以理解:Java开发者通常从事的都是Java Web的工作,对于程序员来说,一个Web项目用到Spring,只是配置一下配置文件而已 ...

最新文章

  1. Jvm 系列(十):Java 即时编译器JIT机制以及编译优化
  2. zookeeper 入门讲解实例 转
  3. 081212 晴
  4. docker命令及挂载
  5. sqlserver2000给账户授予所有的权限_你的位置信息权限设置对了么?
  6. 负载均衡、分布式、集群的关系
  7. DataView筛选出最新的十条数据的方法总结;
  8. 点击startup.bat启动tomcat出现乱码
  9. LinuxQt打包发布
  10. iOS 【真机调试-免证书-开发者信任问题】
  11. 数论系列 求证:设自然数a,b互质,则不能表示成ax+by(x,y为非负整数)的最大整数是ab-a-b
  12. Tableau 网站流量分析案例之页面指标分析(一)
  13. 类似 迈图7608 Monentive7608 上海荟研 高新材料 印刷油墨 合成革离型纸 水性涂料基材润湿剂 超润湿剂资料
  14. 倒立摆的实现 5.步进电机的控制
  15. android 自动挂断,android实现接通和挂断电话
  16. Zabbix 监控功能实现(监控数据库,使用percona 优化数据库的监控,监控java应用,Agent端 主动传输数据,Zabbix proxy 的使用,Zabbix 监控 + 智能降噪告警)
  17. KEAZ128学习(一)----硬件相关
  18. Linux重启Tomcat
  19. excel将一个工作表根据条件拆分成多个sheet工作表
  20. Excel中如何按行排序详细说明

热门文章

  1. VB.NET 策略模式(下机用户类型选择)
  2. IOS判断用邮箱登录验证是不是合法的方法
  3. Invalid attempt to read when no data is present.
  4. 洛谷 P1057 传球游戏
  5. Java Web基础回顾 —HTTP
  6. 关于软件测试里面的Fault Error Failure 差别
  7. 时间戳TimeStamp处理
  8. pycharm 修改新建文件时的头部模板(默认为__author__='...')
  9. Windows 不能在 本地计算机 启动 SQL Server(MSSQLSERVER) 10048
  10. 19/03/17Python笔记