@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的用法,这边不演示了。