Spring框架学习[注解扫描和读取Bean](三)

2014-11-24 03:05:58 · 作者: · 浏览: 2
pe注解的值
  • // annDef.getMetadata().getAnnotationAttributes方法将Bean //中所有的注解和注解的值存放在一个map集合中
  • Map attributes = annDef.getMetadata().getAnnotationAttributes(this.scopeAnnotationType.getName());
  • //将获取到的@Scope注解的值设置到要返回的对象中 if (attributes != null) {
  • metadata.setScopeName((String) attributes.get(value)); //获取@Scope注解中的proxyMode属性值,在创建代理对象时会用到
  • ScopedProxyMode proxyMode = (ScopedProxyMode) attributes.get(proxyMode); //如果@Scope的proxyMode属性值为null、DEFAULT或者NO
  • if (proxyMode == null || proxyMode == ScopedProxyMode.DEFAULT) { //设置proxyMode为NO
  • proxyMode = this.defaultProxyMode; }
  • //为返回的元数据设置proxyMode metadata.setScopedProxyMode(proxyMode);
  • } }
  • //返回解析的作用域元信息对象 return metadata;
  • }

    上述代码中的annDef.getMetadata().getAnnotationAttributes方法就是获取对象中指定类型的注解的值。

    (3).AnnotationConfigUtils处理注解Bean定义类中的通用注解:

    AnnotationConfigUtils类的processCommonDefinitionAnnotations在向容器注册Bean之前,首先对注解Bean定义类中的通用Spring注解进行处理,源码如下:

    [java]
    1. //处理Bean定义中通用注解 static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {
    2. //如果Bean定义中有@Primary注解,则为该Bean设置为autowiring自动依赖注入//装配的首选对象 if (abd.getMetadata().isAnnotated(Primary.class.getName())) {
    3. abd.setPrimary(true); }
    4. //如果Bean定义中有@Lazy注解,则将该Bean预实例化属性设置为@lazy注解的值 if (abd.getMetadata().isAnnotated(Lazy.class.getName())) {
    5. Boolean value = (Boolean) abd.getMetadata().getAnnotationAttributes(Lazy.class.getName()).get(value); abd.setLazyInit(value);
    6. } //如果Bean定义中有@ DependsOn注解,则为该Bean设置所依赖的Bean名称,
    7. //容器将确保在实例化该Bean之前首先实例化所依赖的Bean if (abd.getMetadata().isAnnotated(DependsOn.class.getName())) {
    8. String[] value = (String[]) abd.getMetadata().getAnnotationAttributes(DependsOn.class.getName()).get(value); abd.setDependsOn(value);
    9. } }

      (4).AnnotationConfigUtils根据注解Bean定义类中配置的作用域为其应用相应的代理策略:

      AnnotationConfigUtils类的applyScopedProxyMode方法根据注解Bean定义类中配置的作用域@Scope注解的值,为Bean定义应用相应的代理模式,主要是在Spring面向切面编程(AOP)中使用。源码如下:

      [java]
      1. //根据作用域为Bean应用引用的代码模式 static BeanDefinitionHolder applyScopedProxyMode(
      2. ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) { //获取注解Bean定义类中@Scope注解的proxyMode属性值
      3. ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode(); //如果配置的@Scope注解的proxyMode属性值为NO,则不应用代理模式
      4. if (scopedProxyMode.equals(ScopedProxyMode.NO)) { return definition;
      5. } //获取配置的@Scope注解的proxyMode属性值,如果为TARGET_CLASS,则返
      6. //回true,如果为INTERFACES,则返回false boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);
      7. //为注册的Bean创建相应模式的代理对象 return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass);
      8. }

        这段为Bean引用创建相应模式的代理,如果在Spring面向切面编程(AOP)中涉及到再详细分析,这里不做深入的分析。

        (5).BeanDefinitionReaderUtils向容器注册Bean:

        BeanDefinitionReaderUtils向容器注册载入的Bean我们在第4篇博客中已经分析过,主要是校验Bean定义,然后将Bean添加到容器中一个管理Bean定义的HashMap中,这里就不做分析。

        4.AnnotationConfigApplicationContext扫描指定包及其子包下的注解Bean:

        当创建注解处理容器时,如果传入的初始参数是注解Bean定义类所在的包时,注解容器将扫描给定的包及其子包,将扫描到的注解Bean定义载入并注册。

        (1).Spring中常用的注解:

        a.Component注解:

        [java]
        1. @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME)
        2. @Documented public @interface Component {
        3. String value() default ; }

          b.Service注解:

          [java]
          1. @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME)
          2. @Documented @Component
          3. public @interfac