@Autowired默認優先按類型去容器中找對應的bean,能夠做用在構造函數、成員變量、方法上面,在spring學習之注入這篇已經有例子了,這邊不在講述。
@Autowired有個required屬性,默認是true的,也就是說,當注入的bean是空的狀況,會報異常,若是咱們容許注入的時候爲空,那能夠直接設置爲false。@Autowired(required = false)
此外,咱們還能夠用@Nullable註解表示容許爲空:java
@Autowired public void setMyService(@Nullable MyService myService) { this.myService = myService; }
用java8的java.util.Optionalspring
@Autowired public void setMyService(Optional<MyService> myService) { if (myService.isPresent()) { this.myService = myService.get(); } }
當自動裝配的時候,有多個候選對象,那要怎麼辦呢,@Autowired是根據類型來找對應的bean,若是類型同樣的有多個bean,他怎麼知道要裝配哪一個?
能夠用@Primary註解,來指定默認裝配哪一個。
MyBeansegmentfault
public class MyBean { private String name; public MyBean(String name) { this.name = name; } public String getName() { return name; } }
MyControllerapp
@Controller public class MyController { @Autowired MyBean myBean; public MyBean getMyBean() { return myBean; } }
MyConfig函數
@Configuration @ComponentScan(value="com.learn.annotation2") public class MyConfig { @Bean MyBean zsBean(){ return new MyBean("張三"); } @Bean @Primary MyBean lsBean(){ return new MyBean("李四"); } }
測試代碼學習
@Test public void test() { ApplicationContext app = new AnnotationConfigApplicationContext(MyConfig.class); MyController myController = app.getBean("myController", MyController.class); MyBean myBean = myController.getMyBean(); System.out.println(myBean.getName()); }
運行結果以下:
咱們這邊@Primary註解是在李四上面的,因此輸出結果是李四。測試
既然有默認的裝配類型,那也會讓咱們本身選擇哪一個裝配組件,這個是經過@Qualifier實現的,和@Autowired同樣,能夠做用於成員變量、構造函數、方法裏。這邊只演示成員變量。
MyController,其餘不變。ui
@Controller public class MyController { @Autowired @Qualifier("zsBean") MyBean myBean; public MyBean getMyBean() { return myBean; } }
運行結果以下:
這邊打印張三,是經過@Qualifier("zsBean")指定的。this
@Resource是JSR-250的規範。用法同@Autowired,經過name值來裝配組件,不支持空。
MyControllerspa
@Controller public class MyController { @Resource(name = "lsBean") MyBean myBean; public MyBean getMyBean() { return myBean; } }
MyConfig
@Configuration @ComponentScan(value="com.learn.annotation2") public class MyConfig { @Bean @Primary MyBean zsBean(){ return new MyBean("張三"); } @Bean MyBean lsBean(){ return new MyBean("李四"); } }
測試代碼
@Test public void test() { ApplicationContext app = new AnnotationConfigApplicationContext(MyConfig.class); MyController myController = app.getBean("myController", MyController.class); MyBean myBean = myController.getMyBean(); System.out.println(myBean.getName()); }
運行結果:
雖然@Primary註解在zsBean那邊,可是 @Resource(name = "lsBean")直接指定李四,獲得的結果是李四。若是不執行name呢,打印出來的是張三。
@Inject和@name是JSR-330的規範,若是要使用他,還要引入javax.inject的包,@Inject用法同@Autowired,做用於成員變量、方法、構造函數,能夠支持java.util.Optional和@Nullable,可是沒有required的屬性。@name用法同@Qualifier。
MyController
@Controller public class MyController { @Inject @Named("lsBean") MyBean myBean; public MyBean getMyBean() { return myBean; } }
測試代碼同上,運行結果以下:
@name除了@Qualifier的性質,還有@Component的用法,這邊不演示了。