Spring学习总结(2)-自动装配

  上面说过,IOC的注入有两个地方需要提供依赖关系,一是类的定义中,二是在spring的配置中需要去描述。自动装配则把第二个取消了,即我们仅仅需要在类中提供依赖,继而把对象交给容器管理即可完成注入。在实际开发中,描述类之间的依赖关系通常是大篇幅的,如果使用自动装配则省去了很多配置,并且如果对象的依赖发生更新我们可以不需要去更新配置,但是也带来了一定的缺点。

  说白了就是只需要声明bean,至于对象间的相互引用关系由Spring自己搞定。。

  使用方式:no(不启用),byName(根据名称),byType(根据类型),constructor(构造方法)

<beans ....  
     default-autowire="byType">

</beans>

  自动装配的优点参考文档:https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-autowire

  缺点参考文档:https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-autowired-exceptions

  byType的装配过程:Spring第一步会把所有的bean都加载到容器中,第二步解析时发现Service里有个dao依赖,就会按照依赖去找类属性是这个Dao或者父类是这个Dao的类属性进行注入。

  如果同一个接口有2个实现类,并且还使用接口注入的话就会报错,这是需要改为byName方式,或者根据实现类注入。

  另外,在bean标签中是可以单独指定装配方式的:

<bean id="ClassOne" class="****" autowired="byType">

 

annotation注入方式中的自动装配:

  使用注解@Autowired默认是使用的转配方式是byType,如果没有找到还会使用byName,还没有找到要装配的类,报错。

  注解@Resource默认使用byName,根据属性名来确认的,还可以通过type来指定具体的名称,如 @Resource(type = “IndexImpl”)  

 

spring懒加载

  在Spring配置文件里增加如下语句,表示Spring并不是在在项目启动时全部注入,而是在使用时才会注入,默认false

<beans .....     
  default-lazy-init="true"> </beans>

 

SpringBean的作用域

  singleton:单例

  prototype:标准,每次都是新的对象

  request:限定每个Http请求都是新的对象

  session:将单个bean定义的范围限定为HTTP会话的生命周期。仅在可感知web的Spring ApplicationContext上下文中有效。

  applicaiton:将单个bean定义的范围限定为ServletContext的生命周期。仅在可感知web的Spring ApplicationContext上下文中有效。

  websocket:将单个bean定义的范围限定为WebSocket的生命周期。仅在可感知web的Spring ApplicationContext上下文中有效。

 

@Autowired注解

  @Autowired注解到底使用了那种方式自动装配技术的呢?从Spring源码可以看到,Spring是使用后置处理器AutowiredAnnotationBeanPostProcessor来实现@Autowired的自动装配的,代码如下:

  这里个beanFactory是ConfigurableListableBeanFactory接口,而实现这个接口的类是DefaultListableBeanFactory,在DefaultListableBeanFactory类中的方法resolveDependency又调用了方法doResolveDependency

  通过这段代码,我们可以确定,@Autowired代码是首先是根据byType查找对象,如果查到的对象的数量大于1,再根据byName查找的。

 

注意:

  1、在@Controller/@Service等容器中,默认情况下,scope值是单例-singleton的,也是线程不安全的。

  2、尽量不要在@Controller/@Service等容器中定义静态变量,不论是单例(singleton)还是多实例(prototype)他都是线程不安全的。

  3、默认注入的Bean对象,在不设置scope的时候他也是线程不安全的。

  4、一定要定义变量的话,用ThreadLocal来封装,这个是线程安全的

posted @ 2019-10-02 22:24  闲人鹤  阅读(269)  评论(0编辑  收藏  举报