转载

Spring框架03-IOC应用

Spring IOC应用

Spring IOC基础

Spring框架03-IOC应用

BeanFactory与ApplicationContext区别

  • BeanFactory是Spring框架中IoC容器的顶层接⼝,它只是⽤来定义⼀些基础功能,定义⼀些基础规范
  • ApplicationContext是它的⼀个⼦接⼝,所以ApplicationContext是具备BeanFactory提供的全部功能的

通常,我们称 BeanFactory 为SpringIOC的基础容器 ApplicationContext 是容器的⾼级接⼝,⽐ BeanFactory 要拥有更多的功能,比如说国际化支持和资源访问(xml,java配置类)等等

Spring框架03-IOC应用

启动IOC容器方式

  • Java环境下启动IOC容器

    • ClassPathXmlApplicationContext: 从类的根路径下加载配置文件(推荐使用)
    • FileSystemXmlApplicationContext: 从磁盘路径上加载文件
    • AnnotationConfigApplicationContext: 纯注解模式下加载配置类

Bean的作用范围及⽣命周期

作⽤范围的改变

在spring框架管理Bean对象的创建时,Bean对象默认都是单例的,但是它⽀持配置的⽅式改变作⽤范围。作⽤范围官⽅提供的说明如下图:

Spring框架03-IOC应用

在上图中提供的这些选项中,我们实际开发中⽤到最多的作⽤范围就是singleton(单例模式)和prototype(原型模式,也叫多例模式)。配置⽅式参考下⾯的代码:

<!--配置service对象-->
<bean id="transferService" class="com.lagou.service.impl.TransferServiceImpl" scope="singleton">
</bean>

不同作⽤范围的⽣命周期

单例模式 singleton

  • 对象出⽣:当创建容器时,对象就被创建了
  • 对象活着:只要容器在,对象⼀直活着
  • 对象死亡:当销毁容器时,对象就被销毁了

⼀句话总结:单例模式的bean对象⽣命周期与容器相同

多例模式 prototype

  • 对象出⽣:当使⽤对象时,创建新的对象实例
  • 对象活着:只要对象在使⽤中,就⼀直活着
  • 对象死亡:当对象⻓时间不⽤时,被java的垃圾回收器回收了

⼀句话总结:多例模式的bean对象,spring框架只负责创建,不负责销毁

Bean标签属性

在基于xml的IoC配置中,bean标签是最基础的标签。它表示了IoC容器中的⼀个对象。换句话说,如果⼀个对象想让spring管理,在XML的配置中都需要使⽤此标签配置,Bean标签的属性如下:

  • id属性: ⽤于给bean提供⼀个唯⼀标识。在⼀个标签内部,标识必须唯⼀
  • class属性: ⽤于指定创建Bean对象的全限定类名
  • name属性: ⽤于给bean提供⼀个或多个名称(别名)。多个名称⽤空格分隔
  • factory-bean属性: ⽤于指定创建当前bean对象的⼯⼚bean的唯⼀标识。当指定了此属性之后,class属性失效
  • factory-method属性: ⽤于指定创建当前bean对象的⼯⼚⽅法,如配合factory-bean属性使⽤,则class属性失效。如配合class属性使⽤,则⽅法必须是static的
  • scope属性: ⽤于指定bean对象的作⽤范围。通常情况下就是singleton。当要⽤到多例模式时,可以配置为prototype
  • init-method属性: ⽤于指定bean对象的初始化⽅法,此⽅法会在bean对象装配后调⽤。必须是⼀个⽆参⽅法
  • destory-method属性: ⽤于指定bean对象的销毁⽅法,此⽅法会在bean对象销毁前执⾏。它只能为scope是singleton时起作⽤

DI依赖注⼊的xml配置

  • 依赖注⼊分类

    • 按照注⼊的⽅式分类

      • 构造函数注⼊: 顾名思义,就是利⽤带参构造函数实现对类成员的数据赋值
      • set⽅法注⼊: 它是通过类成员的set⽅法实现数据的注⼊(使⽤最多的)
    • 按照注⼊的数据类型分类

      • 基本类型和String: 注⼊的数据类型是基本类型或者是字符串类型的数据。
      • 其他Bean类型: 注⼊的数据类型是对象类型,称为其他Bean的原因是,这个对象是要求出现在IoC容器中的。那么针对当前Bean来说,就是其他Bean了
      • 复杂类型(集合类型): 注⼊的数据类型是Aarry,List,Set,Map,Properties中的⼀种类型

xml与注解相结合模式

注意:

  • 实际企业开发中,纯xml模式使⽤已经很少了
  • 引⼊注解功能,不需要引⼊额外的jar
  • xml+注解结合模式,xml⽂件依然存在,所以,springIOC容器的启动仍然从加载xml开始
  • 哪些bean的定义写在xml中,哪些bean的定义使⽤注解

    第三⽅jar中的bean定义在xml,⽐如德鲁伊数据库连接池,⾃⼰开发的bean定义使⽤注解

xml中标签与注解的对于(IOC)

xml形式 对应的注解形式
标签 @Component("accountDao"),注解加在类上bean的id属性内容直接配置在注解后⾯如果不配置,默认定义个这个bean的id为类的类名⾸字⺟⼩写;另外,针对分层代码开发提供了@Componenet的三种别名@Controller、@Service、@Repository分别⽤于控制层类、服务层类、dao层类的bean定义,这四个注解的⽤法完全⼀样,只是为了更清晰的区分⽽已
标签的scope属性 @Scope("prototype"),默认单例,注解加在类上
标签的init- method属性 @PostConstruct,注解加在⽅法上,该⽅法就是初始化后调⽤的⽅法
标签的destory- method属性 @PreDestory,注解加在⽅法上,该⽅法就是销毁前调⽤的⽅法

Spring IOC高级特性

lazy-Init延迟加载

Bean的延迟加载(延迟创建)

ApplicationContext容器的默认⾏为是在启动服务器时将所有 singletonbean提前进⾏实例化。提前实例化意味着作为初始化过程的⼀部分,ApplicationContext 实例会创建并配置所有的singleton bean

⽐如:

lazy-init="false",⽴即加载,表示在spring启动时,⽴刻进⾏实例化。

如果不想让⼀个singleton bean 在 ApplicationContext实现初始化时被提前实例化,那么可以将bean

设置为延迟实例化。

设置 lazy-init为 true的 bean将不会在 ApplicationContext启动时提前被实例化,⽽是第⼀次向容器通过 getBean索取 bean时实例化的。

如果⼀个设置了⽴即加载的 bean1,引⽤了⼀个延迟加载的 bean2 ,那么 bean1 在容器启动时被实例化,⽽ bean2 由于被 bean1 引⽤,所以也被实例化,这种情况也符合延时加载的 bean 在第⼀次调⽤时才被实例化的规则。

也可以在容器层次中通过在 元素上使⽤ "default-lazy-init" 属性来控制延时初始化。如下⾯配置:

如果⼀个 bean 的 scope 属性为 scope="pototype" 时,即使设置了 lazy-init="false",容器启动时也不会实例化bean,⽽是调⽤ getBean ⽅法实例化的。

应⽤场景

(1)开启延迟加载⼀定程度提⾼容器启动和运转性能

(2)对于不常使⽤的 Bean设置延迟加载,这样偶尔使⽤的时候再加载,不必要从⼀开始该 Bean就占

⽤资源

2.2FactoryBean和BeanFactory

BeanFactory接⼝是容器的顶级接⼝,定义了容器的⼀些基础⾏为,负责⽣产和管理Bean的⼀个⼯⼚, 具体使⽤它下⾯的⼦接⼝类型,⽐如ApplicationContext;此处我们重点分析FactoryBean

Spring中Bean有两种,⼀种是普通Bean,⼀种是⼯⼚Bean(FactoryBean),FactoryBean可以⽣成某⼀个类型的Bean实例(返回给我们),也就是说我们可以借助于它⾃定义Bean的创建过程。

Bean创建的三种⽅式中的静态⽅法和实例化⽅法和FactoryBean作⽤类似,FactoryBean使⽤较多,尤    其在Spring框架⼀些组件中会使⽤,还有其他框架和Spring框架整合时使⽤

Company类

CompanyFactoryBean类

xml配置

测试,获取FactoryBean产⽣的对象

测试,获取FactoryBean,需要在id之前添加“&”

2.3后置处理器

Spring提供了两种后处理bean的扩展接⼝,分别为 BeanPostProcessor 和

BeanFactoryPostProcessor,两者在使⽤上是有所区别的。

⼯⼚初始化(BeanFactory)—> Bean对象

在BeanFactory初始化之后可以使⽤BeanFactoryPostProcessor进⾏后置处理做⼀些事情

在Bean对象实例化(并不是Bean的整个⽣命周期完成)之后可以使⽤BeanPostProcessor进⾏后置处     理做⼀些事情

注意:对象不⼀定是springbean,⽽springbean⼀定是个对象

SpringBean的⽣命周期

2.3.1 BeanPostProcessor

BeanPostProcessor是针对Bean级别的处理,可以针对某个具体的Bean.

该接⼝提供了两个⽅法,分别在Bean的初始化⽅法前和初始化⽅法后执⾏,具体这个初始化⽅法指的是   什么⽅法,类似我们在定义bean时,定义了init-method所指定的⽅法

定义⼀个类实现了BeanPostProcessor,默认是会对整个Spring容器中所有的bean进⾏处理。如果要对     具体的某个bean处理,可以通过⽅法参数判断,两个类型参数分别为Object和String,第⼀个参数是每个bean的实例,第⼆个参数是每个bean的name或者id属性的值。所以我们可以通过第⼆个参数,来判断我们将要处理的具体的bean。

注意:处理是发⽣在Spring容器的实例化和依赖注⼊之后。

2.3.2BeanFactoryPostProcessor

BeanFactory级别的处理,是针对整个Bean的⼯⼚进⾏处理,典型应

⽤:PropertyPlaceholderConfigurer

此接⼝只提供了⼀个⽅法,⽅法参数为ConfigurableListableBeanFactory,该参数类型定义了⼀些⽅法

其中有个⽅法名为getBeanDefinition的⽅法,我们可以根据此⽅法,找到我们定义bean 的

BeanDefinition对象。然后我们可以对定义的属性进⾏修改,以下是BeanDefinition中的⽅法

⽅法名字类似我们bean标签的属性,setBeanClassName对应bean标签中的class属性,所以当我们拿   到BeanDefinition对象时,我们可以⼿动修改bean标签中所定义的属性值。

B e an D e nition 对象: 我们在XML中定义的bean标签,Spring解析bean标签成为⼀个JavaBean,这个JavaBean就是BeanDefinition

注意:调⽤ BeanFactoryPostProcessor ⽅法时,这时候bean还没有实例化,此时 bean 刚被解析成

BeanDefinition对象

原文  https://segmentfault.com/a/1190000022424723
正文到此结束
Loading...