@Autowired、@Resource是Spring常用的用于自动装备的注解,此外还有@Inject和实现Aware接口等。下面来看看这些注解和接口如何使用和他们之间的区别。
@Autowired:
@Autowired是Spring自己实现的,也是最常用的用于自动装配的注解。
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
boolean required() default true; //是否必须装载属性,默认为true
}
从@Autowired源码中可以看出,@Autowired可以用于构造器、方法、参数、属性和用于注解声明,而我们实际应用中,用的最多的是用于属性装配。先来看一下@Autowired用于属性装配时的特点:
@Autowired用于属性,自动注入:
- 1)默认优先按照类型去容器中找对应的组件:applicationContext.getBean(BookDao.class);找到就赋值
- 2)如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查applicationContext.getBean("bookDao")
- 3)默认情况下,自动装配一定要将属性赋值,没有就会报错; 可以使用@Autowired(required=false);
@Autowired还有一些辅助注解,来规范属性的注入:
- 1)@Qualifier("bookDao"):使用@Qualifier指定需要装配的组件的id,而不再使用属性名
- 2)@Primary:与@Bean组合使用,让Spring进行自动装配的时候,默认使用首选的bean;
也可以继续使用@Qualifier指定需要装配的bean的名字
@Service
public class BookService {
@Qualifier("bookDao") //必须加载实例名为bookDao的BookDao实例
@Autowired(required=false) //非必须装配,bookDao可为null
private BookDao bookDao;
public void print(){
System.out.println(bookDao);
}
@Override
public String toString() {
return "BookService [bookDao=" + bookDao + "]";
}
}
@Configuration
@ComponentScan({"com.zsm"})
public class MainConifgOfAutowired {
@Primary //优先使用实例名为bookDao的BookDao实例
@Bean("bookDao")
public BookDao bookDao(){
BookDao bookDao = new BookDao();
bookDao.setLable("1");
return bookDao;
}
}
@Autowired用于构造器,参数,方法; 都是从容器中获取参数组件的值。
- 1)标注在方法位置:Spring容器创建当前对象时,会调用标注了@Autowired注解的方法。如果方法中有参数,参数值从Spring容器中获取。@Bean+方法参数;参数从容器中获取;默认不写@Autowired效果是一样的;都能自动装配
- 2)标在构造器上:容器启动创建bean时,会优先调用标有@Autowired注解的构造器,如果@Autowired标注在有参构造器上,构造器中的参数必须在容器中可以找到,否则容器启动失败。
- 3)放在参数位置:从Spring容器中获取参数信息,一般都省略@Autowoired注解
@Component
public class Person {
public Person(){
System.out.println("person()");
}
@Autowired
public Person(Book b){ //Book 必须注册进容器,否则容器启动失败
System.out.println("person(Book b)");
}
public Person(String name,String s){
System.out.println("person(String name,String s)");
}
@Autowired
public void autowiredMeth(Person person){
if(person != null)
System.out.println("autowiredMeth");
else
System.out.println("person is null ");
}
}
@ComponentScan(value = {"cn.zsm.entity"})
@Configuration
public class SpringCondiguration {
}
测试:
@Test
public void test2(){
AnnotationConfigApplicationContext application = new AnnotationConfigApplicationContext(SpringCondiguration.class);
}
输出结果:
@Resource、@Inject:
@Resurce是基于JSR 250 规范的注解,@Inject是基于JSR 330规范的注解。
@Resource和@Autowired的主要区别是:@AutoWried按by type自动注入,而@Resource默认按byName自动注入。
@Resource有两个重要属性,分别是name和type:
- 两个属性都不指定时,@Resource默认按照属性名查找,如果查找不到就按照类型查找,如果找不大或找到多个会报异常。
- 只指定name属性,则按照指定的name名查找,如果找不大或找到多个会报异常。
- 只指定type属性,则按照属性信息查找,如果找不大或找到多个会报异常。
- 同时指定name属性和type属性,则按照属性信息和name名查找,如果找不大或找到多个会报异常。
@Inject注解和@Autowired注解的使用方式相同,只是@Inject没有required属性,也不能和@Qualifier和@Primary注解组合使用。