一章搞懂@Order()、@Priority()、@Primary()区别!!!

1,938 阅读3分钟

@Order()

@Order() 注解 可以放在类上、方法上、对象属性上

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Documented
public @interface Order {
   int value() default Ordered.LOWEST_PRECEDENCE;
}

作用:用于控制同一类型的bean被属性注入到一个集合中的bean顺序

@Component
public class UserService {
    @Autowired
    public OrderService orderService1;

    @Autowired
    public List<OrderService> orderServiceS;
}

测试

public class Test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        UserService userService = applicationContext.getBean("userService", UserService.class);
        System.out.println(userService.orderService1);
        System.out.println(userService.orderServiceS);
    }
}

image.png 换一个顺序 image.png

小结:@Order()注解中的值越小、而bean在属性注入到同一类型的集合中就排在越前面

@Priority()

@Priority() 注解 它这个注解是在javax.annotation包中的一个注解、如果你是单独引用的springpom的话还需要加上这个依赖

<dependency>
   <groupId>jakarta.annotation</groupId>
   <artifactId>jakarta.annotation-api</artifactId>
   <version>1.3.5</version>
</dependency>

这个注解可以运用到类上、方法参数上。

@Target({TYPE,PARAMETER})
@Retention(RUNTIME)
@Documented
public @interface Priority {
    int value();
}

上例子

@Component
class OrderService1 implements order{
    public OrderService1() {
        this.ByName();
    }
    @Override
    public void ByName() {
        System.out.println("OrderService1:"+this);
    }
}
@Component
class OrderService2 implements order{
    public OrderService2() {
        this.ByName();
    }
    @Override
    public void ByName() {
        System.out.println("OrderService2:"+this);
    }
}
@Component
class OrderService3 implements order{
    public OrderService3() {
        this.ByName();
    }
    @Override
    public void ByName() {
        System.out.println("OrderService3:"+this);
    }
}

UserService.java

@Component
public class UserService {
    @Autowired
    public order orderService1;
    
    @Autowired
    public List<order> orderServiceS;
}

Test.java

public class Test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        UserService userService = applicationContext.getBean("userService", UserService.class);
        System.out.println(userService.orderService1);
        System.out.println(userService.orderServiceS);
    }
}

如果没有加bean上没有加@Primary()要注意一下的就是UserService类中

// 如果容器中没有一个属性名为orderService1的类会报错、上面我们注入了一个OrderService1类就是、
// @Autowired 注解就会去容器中寻找这个类将其注入到这个属性、后续可以了解一下byType/byName
@Autowired 
public order orderService1; 

但是使用了@Priority()注解就不用关心属性名是否存在这个容器中。

没有加注解之前 image.png

@Component
@Priority(1) //在OrderService3上加上@Priority(1)
class OrderService3 implements order{
    public OrderService3() {
        this.ByName();
    }

    @Override
    public void ByName() {
        System.out.println("OrderService3:"+this);
    }
}

加注解之后 image.png

会发现一个问题不管是单属性注入还是、属性集合注入、会优先注入@Priority()注解标记的bean

@Autowired 
public order orderService1;   // 使用了@Priority()注解就不会关心你属性名存不存在bean中

@Priority()中的值越小注入单一属性的时候就会优先使用、而注入到对象集合的时候会排在前面。

@Priority()@Order()区别

  • @Priority()会让使用@Autowired注入单一属性值的时候优先使用@Priority()配置的bean、也会改变注入的集合对象在集合中的顺序、越小越在前面

  • @Order()不让单一属性优先注入使用、而它会改变注入的集合对象在集合中的顺序、越小越在前面

  • 如果是属性同一对象注入到集合中的优先级使用

    •  @Order@Priority 》无
      

分别使用到同一类型不同类上方使用@Order(-1)@Priority(1)

@Component
@Order(-1)
class OrderService2 implements order{
    public OrderService2() {
        this.ByName();
    }

    @Override
    public void ByName() {
        System.out.println("OrderService2:"+this);
    }
}

@Component
@Priority(1)
class OrderService3 implements order{
    public OrderService3() {
        this.ByName();
    }

    @Override
    public void ByName() {
        System.out.println("OrderService3:"+this);
    }
}

结果

image.png

会发现使用@Order()的注解的类在集合中排在最前面、而第二的就是使用@Priority()注解的类型、但是单一属性对象值注入的就是使用@Priority()的类、由此可以说明@Order()注解不会影响单一属性对象的注入

@Primary()

@Primary()注解

这个注解可以运用到类上、方法上。

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Primary {
}

上例子

@Component
@Primary()
class OrderService1 implements order{
    public OrderService1() {
        this.ByName();
    }

    @Override
    public void ByName() {
        System.out.println("OrderService1:"+this);
    }
}

@Component
@Order(-1)
class OrderService2 implements order{
    public OrderService2() {
        this.ByName();
    }

    @Override
    public void ByName() {
        System.out.println("OrderService2:"+this);
    }
}

@Component
@Priority(1)
class OrderService3 implements order{
    public OrderService3() {
        this.ByName();
    }

    @Override
    public void ByName() {
        System.out.println("OrderService3:"+this);
    }
}   

UserService.java

@Component
public class UserService {
    @Autowired
    public order orderService1;
    
    @Autowired
    public List<order> orderServiceS;
}

Test.java

public class Test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        UserService userService = applicationContext.getBean("userService", UserService.class);
        System.out.println(userService.orderService1);
        System.out.println(userService.orderServiceS);
    }
}

运行结果

image.png

会发现使用@Autowired注入单一属性值会优先使用@Primary()注解标记的类、而集合中却不会发生顺序的变化

注意:不能使用多个@Primary()注解标记同一个类型的bean

总结

  • 使用@Autowired注入单一属性值的时候、@Priority()@Primary()会优先选择被标记的对象、优先级@Primary()>@Priority()
  • 使用@Autowired注入同一类型的集合属性值的时候、@Primary()不会对集合中的对象值顺序发生变化、而@Order()@Priority()会改变集合中的值顺序优先级@Order > @Priority

码云demo地址:gitee.com/wei_duhao/t…