Spring中 @Primary注解的作用
下面是Primary注解的源码:
package org.springframework.context.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; /** * Indicates that a bean should be given preference when multiple candidates * are qualified to autowire a single-valued dependency. If exactly one * primary bean exists among the candidates, it will be the autowired value. * ... */ @Target({ ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Primary { }
上面注释大致含义是:当我们使用自动配置的方式注入Bean时,如果这个Bean有多个候选者,如果其中一个候选者具有@Primary注解修饰,该候选者会被选中,作为自动配置的值。
我们可以做一下实验:
我们创建一个CarController,在里面使用@Autowird自动注入一个ICarService的对象。
package com.lbb.controller; import com.lbb.service.ICarService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping(value = "/car") public class CarController { @Autowired private ICarService carService; @GetMapping(value = "/drive") public void drive() { this.carService.drive(); } }
下面是ICarService接口,以及其两个实现类BMWCarService、AudiCarService。
package com.lbb.service; public interface ICarService { void drive(); }
package com.lbb.service.impl; import com.lbb.service.ICarService; import org.springframework.stereotype.Service; @Service public class BMWCarService implements ICarService { @Override public void drive() { System.out.println("bmw drive"); } }
package com.lbb.service.impl; import com.lbb.service.ICarService; import org.springframework.stereotype.Service; @Service public class AudiCarService implements ICarService { @Override public void drive() { System.out.println("audi drive"); } }
我们启动项目,由于存在两个ICarService的实现类,Spring不知道为我们注入哪一个,就会报如下的异常:
*************************** APPLICATION FAILED TO START *************************** Description: Field carService in com.lbb.controller.CarController required a single bean, but 2 were found: - audiCarService: defined in file [D:ideaprojects est argetclassescomlbbserviceimplAudiCarService.class] - BMWCarService: defined in file [D:ideaprojects est argetclassescomlbbserviceimplBMWCarService.class] Action: Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed Process finished with exit code 1
在打印出的信息中,它会提示推荐我们使用@Primary注解或@Qualifier注解来解决该问题。
下面我们就使用@Primary注解来进行处理,如下所示:
package com.lbb.service.impl; import com.lbb.service.ICarService; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Service; @Primary @Service public class AudiCarService implements ICarService { @Override public void drive() { System.out.println("audi drive"); } }
此时启动项目,发现项目启动正常,说明Spring已经帮我们自动装配完成,我们请求一下CarController来看一下到底自动注入的是哪一个实现类。
通过控制台打印,我们可以看到是AudiCarService中的drive方法被触发了,说明Spring为我们自动注入的是经过@Primary注解修饰的AudiCarService。
所以@Primary注解的作用就是当一个接口存在多个实现类时,我们就可以通过@Primary注解来指明哪个实现类作为首选进行自动装配注入。
下一篇:
建立备份域控服务器,备份域控制器