spring學習之注入(二)

@Autowired

@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();
    }
}

@Primary

當自動裝配的時候,有多個候選對象,那要怎麼辦呢,@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());
}

運行結果以下:
image.png
咱們這邊@Primary註解是在李四上面的,因此輸出結果是李四。測試

@Qualifier

既然有默認的裝配類型,那也會讓咱們本身選擇哪一個裝配組件,這個是經過@Qualifier實現的,和@Autowired同樣,能夠做用於成員變量、構造函數、方法裏。這邊只演示成員變量。
MyController,其餘不變。ui

@Controller
public class MyController {
    @Autowired
    @Qualifier("zsBean")
    MyBean myBean;

    public MyBean getMyBean() {
        return myBean;
    }
}

運行結果以下:
image.png
這邊打印張三,是經過@Qualifier("zsBean")指定的。this

@Resource

@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());
}

運行結果:
image.png
雖然@Primary註解在zsBean那邊,可是 @Resource(name = "lsBean")直接指定李四,獲得的結果是李四。若是不執行name呢,打印出來的是張三。

@Inject和@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;
    }
}

測試代碼同上,運行結果以下:
image.png@name除了@Qualifier的性質,還有@Component的用法,這邊不演示了。

相關文章
相關標籤/搜索