常用的自动装配注解@Autowired @RequiredArgsConstructor @AllArgsConstructor

      《spring实战》中给装配下了一个定义:创建应用对象之间协作关系的行为称为装配。也就是说当一个对象的属性是另一个对象时,实例化时,需要为这个对象属性进行实例化。这就是装配。

如果一个对象只通过接口来表明依赖关系,那么这种依赖就能够在对象本身毫不知情的情况下,用不同的具体实现进行切换。但是这样会存在一个问题,在传统的依赖注入配置中,我们必须要明确要给属性装配哪一个bean的引用,一旦bean很多,就不好维护了。基于这样的场景,spring使用注解来进行自动装配,解决这个问题。自动装配就是开发人员不必知道具体要装配哪个bean的引用,这个识别的工作会由spring来完成。与自动装配配合的还有“自动检测”,这 个动作会自动识别哪些类需要被配置成bean,进而来进行装配。这样我们就明白了,自动装配是为了将依赖注入“自动化”的一个简化配置的操作。


装配分为三种:byName, byType, constructor。

  • byName就是会将与属性的名字一样的bean进行装配。
  • byType就是将同属性一样类型的bean进行装配。
  • constructor就是通过构造器来将类型与参数相同的bean进行装配。
public interface AutowireCapableBeanFactory extends BeanFactory {
    int AUTOWIRE_NO = 0;
    int AUTOWIRE_BY_NAME = 1;
    int AUTOWIRE_BY_TYPE = 2;
    int AUTOWIRE_CONSTRUCTOR = 3;
}

byType的 @Autowired(spring提供的),@Inject(java ee提供)

@Autowired注解是byType类型的,这个注解可以用在属性上面,setter方面上面以及构造器上面。使用这个注解时,就不需要在类中为属性添加setter方法了。但是这个属性是强制性的,也就是说必须得装配上,如果没有找到合适的bean能够装配上,就会抛出异常。这时可以使用required=false来允许可以不被装配上,默认值为true。当required=true时,@Autowired要求必须装配,但是在没有bean能装配上时,就会抛出异常:NoSuchBeanDefinitionException,如果required=false时,则不会抛出异常。

  • @Inject必须是强制装配的,没有required属性,也就是不能为null,如果不存在匹配的bean,会抛出异常。
  • 自动装配时,装配的bean必须是唯一与属性进行吻合的,不能多也不能少,有且只有一个可以进行装配的bean,才能自动装配成功。否则会抛出异常。

byName的 @Qualifier(spring提供的),@Named(java ee提供),@Resource(java ee提供)

一种情况是同时有多个bean是一个类型的,也会抛出这个异常。此时需要进一步明确要装配哪一个Bean,这时可以组合使用

@Qualifier注解使用byName进行装配,这样可以在多个类型一样的bean中,明确使用哪一个名字的bean来进行装配。@Qualifier注解起到了缩小自动装配候选bean的范围的作用。

@Autowired与@Qualifier是spring提供的 ,@Inject与@Named是java ee的。

constructor 的@Data  @RequiredArgsConstructor @AllArgsConstructor

@Component
@Slf4j
@AllArgsConstructor
class NoNeedInspectValidator {

    private final MaterialProxy materialProxy;
    private final ResultVOBuilder resultVOBuilder;
}
  • @Data
/**
 * Generates getters for all fields, a useful toString method, and hashCode and equals implementations that check
 * all non-transient fields. Will also generate setters for all non-final fields, as well as a constructor.
 * 

* Equivalent to {@code @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode}. *

* Complete documentation is found at the project lombok features page for @Data. * * @see Getter * @see Setter * @see RequiredArgsConstructor * @see ToString * @see EqualsAndHashCode * @see lombok.Value */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface Data { /** * If you specify a static constructor name, then the generated constructor will be private, and * instead a static factory method is created that other classes can use to create instances. * We suggest the name: "of", like so: * *

	 *     public @Data(staticConstructor = "of") class Point { final int x, y; }
	 * 
* * Default: No static constructor, instead the normal constructor is public. * * @return Name of static 'constructor' method to generate (blank = generate a normal constructor). */ String staticConstructor() default ""; }

根据源码可以看到  注解@Data含有@RequiredArgsConstructor

  • @RequiredArgsConstructor
/**
 * Generates a constructor with required arguments.
 * Required arguments are final fields and fields with constraints such as {@code @NonNull}.
 * 

* Complete documentation is found at the project lombok features page for @Constructor. *

* Even though it is not listed, this annotation also has the {@code onConstructor} parameter. See the full documentation for more details. * * @see NoArgsConstructor * @see AllArgsConstructor */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface RequiredArgsConstructor { /** * If set, the generated constructor will be private, and an additional static 'constructor' * is generated with the same argument list that wraps the real constructor. * * Such a static 'constructor' is primarily useful as it infers type arguments. * * @return Name of static 'constructor' method to generate (blank = generate a normal constructor). */ String staticName() default ""; /** * Any annotations listed here are put on the generated constructor. * The syntax for this feature depends on JDK version (nothing we can do about that; it's to work around javac bugs).
* up to JDK7:
* {@code @RequiredArgsConstructor(onConstructor=@__({@AnnotationsGoHere}))}
* from JDK8:
* {@code @RequiredArgsConstructor(onConstructor_={@AnnotationsGohere})} // note the underscore after {@code onConstructor}. * * @return List of annotations to apply to the generated constructor. */ AnyAnnotation[] onConstructor() default {}; /** * Sets the access level of the constructor. By default, generated constructors are {@code public}. * * @return The constructor will be generated with this access modifier. */ AccessLevel access() default lombok.AccessLevel.PUBLIC; /** * Placeholder annotation to enable the placement of annotations on the generated code. * @deprecated Don't use this annotation, ever - Read the documentation. */ @Deprecated @Retention(RetentionPolicy.SOURCE) @Target({}) @interface AnyAnnotation {} }

 根据源码可以看到  Required arguments are final fields and fields with constraints such as {@code @NonNull}.

会生成一个包含常量,和标识了NotNull的变量的构造方法。生成的构造方法是私有的private

  •  @AllArgsConstructor

会生成一个包含所有变量的构造方法

区别:执行顺序

Constructor >> @Autowired


 

你可能感兴趣的:(Spring,boot)