zoukankan      html  css  js  c++  java
  • @Autowired

    @Autowired注解了。这个注解的功能就是为我们注入一个定义好的bean。

    @Autowired注解用法

    将@Autowired注解应用于构造函数

    public class MovieRecommender {
     
        private final CustomerPreferenceDao customerPreferenceDao;
     
        @Autowired
        public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
            this.customerPreferenceDao = customerPreferenceDao;
        }
     
        // ...
    }

    将@Autowired注释应用于setter方法

    public class SimpleMovieLister {
     
        private MovieFinder movieFinder;
     
        @Autowired
        public void setMovieFinder(MovieFinder movieFinder) {
            this.movieFinder = movieFinder;
        }
     
        // ...
    }

    将@Autowired注释应用于具有任意名称和多个参数的方法

    public class MovieRecommender {
     
        private MovieCatalog movieCatalog;
     
        private CustomerPreferenceDao customerPreferenceDao;
     
        @Autowired
        public void prepare(MovieCatalog movieCatalog,
                CustomerPreferenceDao customerPreferenceDao) {
            this.movieCatalog = movieCatalog;
            this.customerPreferenceDao = customerPreferenceDao;
        }
     
        // ...
    }

    将@Autowired应用于字段,或者将其与构造函数混合

    public class MovieRecommender {
     
        private final CustomerPreferenceDao customerPreferenceDao;
     
        @Autowired
        private MovieCatalog movieCatalog;
     
        @Autowired
        public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
            this.customerPreferenceDao = customerPreferenceDao;
        }
     
        // ...
    }

    将@Autowired注释添加到需要该类型数组的字段或方法,则spring会从ApplicationContext中搜寻符合指定类型的所有bean

    这个注解是属于spring的容器配置的一个注解,与它同属容器配置的注解还有:@Required,@Primary, @Qualifier等等。因此@Autowired注解是一个用于容器(container)配置的注解。

    将Spring容器中的bean自动的和我们需要这个bean的类组装在一起协同使用。

    java的注解实现的核心技术是反射

    ===》

    @Override

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.SOURCE)
    public @interface Override {
    }

    @Override注解使用java官方提供的注解,它的定义里面并没有任何的实现逻辑。注意,所有的注解几乎都是这样的,注解只能是被看作元数据,它不包含任何业务逻辑。 注解更像是一个标签,一个声明

    他的功能是重写一个方法,而他的实现者就是JVM,java虚拟机,java虚拟机在字节码层面实现了这个功能。

    但是对于开发人员,虚拟机的实现是无法控制的东西,也不能用于自定义注解。所以,如果是我们自己想定义一个独一无二的注解的话,则我们需要自己为注解写一个实现逻辑,换言之,我们需要实现自己注解特定逻辑的功能。

    《《《《《《=========》》》》》》》》

    自己实现一个注解:

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
     
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface SimpleAnnotation {
        String value();
    }

    【这个注释里面只定义了一个字符传,它的目标注释对象是方法,保留策略是在运行期间】
    使用这个注解:

    public class UseAnnotation {
     
        @SimpleAnnotation("testStringValue")
        public void testMethod(){
            //do something here
        }
     
    }

    • 利用反射机制获取一个类的Class对象
    • 通过这个class对象可以去获取他的每一个方法method,或字段Field等等
    • Method,Field等类提供了类似于getAnnotation的方法来获取这个一个字段的所有注解
    • 拿到注解之后,我们可以判断这个注解是否是我们要实现的注解,如果是则实现注解逻辑

    现在我们来实现一下这个逻辑

    private static void annotationLogic() {

         Class useAnnotationClass = UseAnnotation.class;
         for(Method method : useAnnotationClass.getMethods()) {
             SimpleAnnotation simpleAnnotation = (SimpleAnnotation)method.getAnnotation(SimpleAnnotation.class);
             if(simpleAnnotation != null) {
                 System.out.println(" Method Name : " + method.getName());
                 System.out.println(" value : " + simpleAnnotation.value());
                 System.out.println(" --------------------------- ");
             }
         }
     }

     

    ===

    借助于java的反射我们可以直接拿到一个类里所有的方法,然后再拿到方法上的注解,当然,我们也可以拿到字段上的注解。借助于反射我们可以拿到几乎任何属于一个类的东西。

     

    @Autowired这个注解在spring的源代码里的定义

    package org.springframework.beans.factory.annotation;
     
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
     
    @Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Autowired {
        boolean required() default true;
    }

    Spring对autowire注解的实现逻辑位于类:AutowiredAnnotationBeanPostProcessor之中

    private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
      LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<>();
      Class<?> targetClass = clazz;//需要处理的目标类
           
      do {
       final LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<>();
     
                /*通过反射获取该类所有的字段,并遍历每一个字段,并通过方法findAutowiredAnnotation遍历每一个字段的所用注解,并如果用autowired修饰了,则返回auotowired相关属性*/  
     
       ReflectionUtils.doWithLocalFields(targetClass, field -> {
        AnnotationAttributes ann = findAutowiredAnnotation(field);
        if (ann != null) {//校验autowired注解是否用在了static方法上
         if (Modifier.isStatic(field.getModifiers())) {
          if (logger.isWarnEnabled()) {
           logger.warn("Autowired annotation is not supported on static fields: " + field);
          }
          return;
         }//判断是否指定了required
         boolean required = determineRequiredStatus(ann);
         currElements.add(new AutowiredFieldElement(field, required));
        }
       });
                //和上面一样的逻辑,但是是通过反射处理类的method
       ReflectionUtils.doWithLocalMethods(targetClass, method -> {
        Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
        if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
         return;
        }
        AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
        if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
         if (Modifier.isStatic(method.getModifiers())) {
          if (logger.isWarnEnabled()) {
           logger.warn("Autowired annotation is not supported on static methods: " + method);
          }
          return;
         }
         if (method.getParameterCount() == 0) {
          if (logger.isWarnEnabled()) {
           logger.warn("Autowired annotation should only be used on methods with parameters: " +
             method);
          }
         }
         boolean required = determineRequiredStatus(ann);
         PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                       currElements.add(new AutowiredMethodElement(method, required, pd));
        }
       });
        //用@Autowired修饰的注解可能不止一个,因此都加在currElements这个容器里面,一起处理  
       elements.addAll(0, currElements);
       targetClass = targetClass.getSuperclass();
      }
      while (targetClass != null && targetClass != Object.class);
     
      return new InjectionMetadata(clazz, elements);
     }

  • 相关阅读:
    文佳夹之删除
    猜谜小游戏
    python小知识点
    【bzoj4516】[Sdoi2016]生成魔咒 后缀数组+倍增RMQ+STL-set
    【bzoj3362/3363/3364/3365】[Usaco2004 Feb]树上问题杂烩 并查集/树的直径/LCA/树的点分治
    【poj1741】Tree 树的点分治
    【bzoj2946】[Poi2000]公共串 后缀数组+二分
    【bzoj2157】旅游 树链剖分+线段树
    【bzoj2743】[HEOI2012]采花 树状数组
    【bzoj2705】[SDOI2012]Longge的问题 欧拉函数
  • 原文地址:https://www.cnblogs.com/KL2016/p/14929148.html
Copyright © 2011-2022 走看看