Spring核心技术--IoC container用法详解

一直在使用Spring提供的IoC容器, 但是始终没有系统化的梳理一下. 今天在这里写下, 也是以备以后参考之用.Ioc container的核心是BeanFactory接口, 它提供的方法能够管理任何类型的对象. ApplicationContext是它的子接口, 集成了Spring AOP的特性.BeanFactory or ApplicationContext? BeanFactory目前
摘要由CSDN通过智能技术生成

一直在使用Spring提供的IoC容器, 但是始终没有系统化的梳理一下. 今天在这里写下, 也是以备以后参考之用.

Ioc container的核心是BeanFactory接口, 它提供的方法能够管理任何类型的对象. ApplicationContext是它的子接口, 集成了Spring AOP的特性.

BeanFactory or ApplicationContext?

BeanFactory目前只是Spring为了维持向后兼容性而保留的接口, 任何新开发的框架或者程序应该使用ApplicationContext而不是BeanFactory.

那么ApplicationContext相比BeanFactory提供了哪些好处呢? 简单的来说就是很多增强的功能, 更细粒度的干预bean生命周期的定制, AOP, 国际化, 事件支持等, 详见下表:

所有的bean在使用前都需要在ApplicationContext注册(register), 常用的有以下几种形式:

  • xml形式定义的;
  • 注解定义;
  • Java Config
  • 手动注册在Spring容器之外实例化的bean;

Dependency Injection的实现方式

一共有三种方法: 构造器注入, 设值注入和方法注入. 构造器注入在设值注入之前.

  • 构造器注入: 注入强制性的依赖.
  • 设值注入: 注入可选依赖或配置(例如@ConfigurationProperties); 当设置注入加入了@Required标识, 就会变成一个强制性依赖.
  • 方法注入: 通常是在bean构造后对bean进行增强设置.

Constructor-based

构造器注入是推荐的方式, 能够实现一个immutable的bean, 确保所有的依赖不是null. 并能够保证调用者使用时, 依赖是实例化完成的.

无需提供getter/setter方法.

setter-based

设值注入应被仅用于注入可选依赖, 或者是能够被赋予默认值的依赖.

使用设值注入的好处是, 能够在之后通过setter方法进行注入的变更, 在JMX MBeans管理上必须使用此种方式.

方法注入

下面是一个例子:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
   

    @Autowired // 自动注入--方法注入参数auth, 对已创建的AuthenticationManagerBuilder类型的bean进行增强.
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
   
        auth.inMemoryAuthentication().withUser("admin").password("admin").roles("USER");
    }
}

依赖解析步骤

如果bean是单例的, 并且被标注为pre-instantiated(默认就是这个)会在容器创建的时候被创建. 否则的话会按需创建.

lazy-initialized beans

通常来讲单例bean会在容器创建的时候初始化, 并且会按照依赖关系顺次进行初始化, 但是你也可以通过指定lazy-init=true到某个bean上使其在第一次使用的时候才被初始化.

注意: 即使某个bean开启了lazy-init, 也不一定是延迟初始化的, 因为如果依赖它的bean是单例的, 且没有开启延迟初始化, 那么Spring容器为了保证准确性, 会将这个bean也立即初始化.

Bean作用域(Bean Scopes)

bean一共有七种作用域:

作用域 描述
singleton 默认, 单例, 通常用于无状态bean, 如dao. service, controller等
prototype 原型, 每次调用产生一个新的实例, 通常用在domain object上. 相当于java的new关键字, Spring在实例化bean之后, 执行完initialization lifecycle callback, 之后就不在负责这个bean的生命周期了, 完全交给客户端负责
request HTTP 请求范围
session HTTP Session范围
application ServletContext的生命周期一致, 也就是web应用的范围
websocket 和一个WebSocket的生命周期一致

request, session, application, websocket作用域

这些作用域需要线程与Http Request或者Http Sesson对象绑定. 当使用Spring MVC时, 自动绑定.

使用以下注解在bean上显式指定:

  • @RequestScope
  • @SessionScope
  • @ApplicationScope
application scope

ServletContext级别的, 作为一个ServletContext的attribute存取, 这个范围非常像singleton范围, 但是有以下两点主要区别:

  • 它是与ServletContext绑定, 不是与ApplicatinContext绑定. 一个ServletContext可以有多个ApplicationContext. 也就是说, application scope的bean是与ApplicationContext平行的, 二者都是ServletContext的一个属性.
  • 它是ServletContext的一个属性.

代理

一般有两种类型:

  • interface-based proxy, 典型的是JDK内置的动态代理
  • 一种是inherated-based proxy, 典型的是CGLIB

interface-based proxy

优点是不需要引入额外的库依赖, 缺点是想要代理的方法必须是在被代理类实现的接口中定义的.

inherated-based proxy

缺点是需要引入额外依赖, 优点是可以代理所有的共有类型方法.

Bean生命周期(lifecycle)

  • initialization callback 使用@PostConstruct
  • de
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值