通过注解配置bean。

一、知识点

(1)项目结构

1

配置关联关系:

(2)预期实现效果

  1. usercontroller.execute()将执行。
  2. 然后执行userservice.add()。
  3. 最后执行userrepository.save()。

实际结果:

没有往下执行了。

因为ioc容器中没有userservice这个bean,空指针无法往下执行了,这几个类没有关联起来。

(3)组件装配

<context:component-scan>元素会自动注册AutowiredAnnotationBeanPostProcessor实例,该实例可以自动装配具有@Autowired和@Resource,@Inject注解的属性。

其中最常用的就是@Autowired。

加上@Autowired属性之后:

再次执行:

发现userservice.add()执行了。

但是userrepository.save()依然没有执行,这是因为userrepository对象没有自动装配。

在userrepository也配置了@Autowired注解之后:

或者把@Autowired注释写在set方法上也是可以的,spring会自动通过set方法完成对象的注入:

结果为:

所有函数都正确执行了。

(4)改造一下接口,把test对象也加入进来

运行结果:

因为自动装配,test这个对象也正确的被实例化了

那么问题来了,假如test不再是ioc容器中的一员了,那么还能找到test吗?

注释掉@Component注解:

结果报错了:

容器启动报错,没有找到能自动装配的bean依赖。

(5)使用@Autowired自动装配bean

  1. @Autowired注解自动装配具有兼容类型的单个bean属性。
  2. 构造器,普通字段(即使是非public),一切具有参数的方法都可以应用@Autowired注解。
  3. 默认情况下,所有使用@Autowired注解的属性都需要被设置在ioc容器中,当spring找不到匹配的bean装配属性时,会抛出异常。

(6)required=false

设置@Autowired(required = false)非必须。

即使test不在ioc容器中,依然能够运行,只是获取不到test这个bean而已,会返回null,但是不会报错:

(7)不能存在非唯一的bean

尝试在ioc容器里设置两个bean,都去实现userrepository接口:

那么@Autowired的时候会装配哪一个呢?

结果报错了:

spring不知道注入哪个对象。

解决办法:

1.让这个bean的名字刚好和属性名字一致

@Repository(“类名”)

算是一个区分的办法。

2.如果有两个一样的bean,那么自动装配先倾向于去找注解名

因为在userservice中,类名为userrepository,所以spring倾向于先找@Repository(“userrepository”)这个注解名。

一旦newuserrepository.java加上@Repository(“userrepository”)

就会自动装配newuserrepository.java,不会再纠结info.java也实现了userrepository 接口。

3.可以在实例化的时候指定是哪个bean

  1. @Autowired
  2. @Qualifier(“newuserrepository”)

这样自动注入的时候就指定了newuserrepository这个类了。

结果为:

注释在字段上,和注释在set方法上效果是一样的:

(8)使用@Resource或者@Inject自动装配bean

spring还支持@Resource或者@Inject注解,这两个注解和@Autowired注解公用类似。

  1. @Resource注解要求提供一个bean名称的属性,若该属性为空,则自动采用标注处的变量或方法名作为bean的名称。
  2. @Inject和@Autowired注解一样也是按类型匹配注入的bean,但是没有reqired属性。
  3. 建议使用@Autowired注解。

二、总结

建议都去使用@Autowired方法,同时避免重复类实现同一接口的问题。

发表评论

电子邮件地址不会被公开。 必填项已用*标注