常⽤的⾃动装配注解
@Autowired@RequiredArgsConstructor@A。。。
《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.
* <p>
* Equivalent to {@code @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode}.
* <p>
* Complete documentation is found at <a href="/features/Data">the project lombok features page for @Data</a>. *
* @see Getter
* @see Setter
* @see RequiredArgsConstructor
* @see ToString
* @see EqualsAndHashCode
* @see lombok.Value
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
resource和autowired注解的区别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:
*
* <pre>
* public @Data(staticConstructor = "of") class Point { final int x, y; }
* </pre>
*
* 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}.
* <p>
* Complete documentation is found at <a href="/features/Constructor">the project lombok features page for @Constructor</a>. * <p>
* 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).<br>
* up to JDK7:<br>
* {@code @RequiredArgsConstructor(onConstructor=@__({@AnnotationsGoHere}))}<br>
* from JDK8:<br>
* {@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
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论