使用@autowired实现对象的依赖注入是spring的核心功能之一,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。
1.使用@autowired实现依赖注入(DI)
@autowired要做的工作其实就是初始化我们类的成员变量,不管是model中的属性字段,还是serviceImpl中我们要引用的其他接口对象,我们都可以使用@autowired来进行初始化操作。
使用@autowired注解最大的好处就是简化我们操作。之前我们要将对象注入到IOC容器中,需要在xml中配置bean和property,并且提供对应的get、set方法。如果对象和属性比较多的时候这样就非常麻烦,特别是当要注入的类中还有其他自定义的引用对象时,就更加麻烦了。
1. 将对象注入IOC容器之前最原始的配置
我们需要在xml中进行配置
而且我们知道使用property赋值时,是调用对象属性的get、set方法进行的,所以我们还必须提供对应的get、set方法
当我们需要引用其他的对象时还需要将该对象用同样的方式注入IOC容器中,然后去ref引用
非常的繁琐
2. 之后我们使用注解将在IOC容器注入对象的工作替代了
为需要注入IOC容器的class添加注解(@Repository、@Service、@Controller、@Component)
我们只需要在xml中添加包扫描配置,IOC容器就会自动将我们配置好的class注入到容器中,非常的方便
但是这样我们就遇到了一个新问题,我们如何将自动注入的对象进行初始化呢?
3. 当我们不能在xml中进行初始化赋值时,我们为对象初始化赋值要么在获取对象后,调用set方法进行赋值
要么在类中直接指定默认值
如果是一个引用数据类型,我们还需要new一个对象然后为这个属性赋值
当我们这样做时,我们封装属性的get、set方法就变的不再重要因为它们也是干这个事的(这里只是为了演示,属性还是封装起来比较好)
4.我已经用的spring了,对象我都给你了,我还要自己创建对象么?
当然不用,@autowired就是为了干这个事诞生的
@autowired就是为了干之前我们 new 对象这个事的,它会为我们“new”一个对象并且为属性赋值,当然这个属性并不是spring new的而是我们注入到IOC容器中的, @autowired会根据一定的规则去到IOC容器中匹配对应的对象,然后将匹配到的对象赋值过来
因此使用@autowired注解是可以省略get、set方法的
注意:
1.@autowired标注的属性必须存在于IOC容器中,否则匹配不到会报错,nosuchbean
2.使用@autowired的class也必须在IOC容器中存在
2.@autowired注入对象的规则
2.1. @autowired的对象匹配规则
先根据被标注属性的类型进行匹配,匹配到容器中只有一个则取出赋值,没有则报错,有多个类型相同的对象时,则将被标注的属性名作为id在容器中匹配,如果匹配到则取出赋值,如果没有则报错这个规则其实是和“xml中bean的属性 autowire=“constructor””是一样的
测试代码包结构:
OrganizationServiceImpl:
OrganizationServiceExtImpl:
UserServiceImpl:
Test:
1.没有注入OrganizationServiceExtImpl时,IOC容器中只有一个OrganizationService类型的对象,所以属性名是什么并无所谓
2.将OrganizationServiceExtImpl注入时,IOC容器中有两个OrganizationService类型的对象,且没有指定正确的属性名,就会报错NoUniqueBeanDefinitionException
我们可以将属性名称改成要注入的对象名称,也可以使用@Qualifier注解为当前对象指定一个id,以便@Autowired在IOC容器中进行查找修改属性名:
指定id:
注意:当我们指定的id和属性名在IOC容器中同时存在,会优先进行@Qualifier指定的id的匹配
3.当类型没有匹配到,属性名没有匹配到,且指定的@Qualifier也没有匹配到时,就会报错。我们可以指定@Autowired的equired 属性,设置为false来为对象赋值null,来防止程序报错
@Autowired(required = false)
@Qualifier("organizationServiceExtImpl222")
private OrganizationService organizationServiceImpl222;
@Override
public void saveOrUpdate() {
if(organizationServiceImpl222 != null) {
organizationServiceImpl222.saveOrUpdate();
}
System.out.println("保存了用户....");
}
2.@autowired在不同地方的标注
@autowired可以标注在属性、方法、构造器和注解上
@autowired标注在方法上,该方法在容器启动时会自动运行,并将形参赋值,同时可以在方法的形参上指定@Qualifier来指定要加载那个对象
@Autowired
public void testAutowired(@Qualifier("organizationServiceExtImpl")OrganizationService organization) {
System.out.println("测试testAutowired");
if(organization != null) {
organization.saveOrUpdate();
}
System.out.println("保存了用户....");
}