SpringFramework核心概念
程序的编写永远最求更低的耦合。
Spring的解决方案:
- 使用对象时,在程序中不要组东使用new产生对象,转换由外部提供对象
IoC(Inversion of Control)控制反转 & DI(Dependency Injection)依赖注入
- 使用对象时,由主动new产生对象变为由外部提供对象,此过程中对象的创建权由程序转移到外部,此思想称为控制反转
- Spring技术对IoC思想进行了实现
    - Spring提供了一个容器,称为IoC容器,用来充当Ioc思想中的外部
- IoC容器负责对象的创建、初始化等一系列工作,被创建或者被管理的对象在IoC容器中统称为Bean
 
- DI(Dependency Injection)依赖注入
    - 在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入
 
- 目标:充分解耦
    - 使用IoC容器管理bean(IoC)
- 在IoC容器中将由依赖关系的bean进行关系绑定
 
- 最终效果
    - 使用对象时不仅可以直接从IoC容器中获取,并且获取到的bean已经绑定了所有的依赖关系
 
bean
- 由IoC容器管理的Bean
IoC入门
- 管理什么?(service和dao)
- 如何将被管理的对象告知IoC容器?(配置)
- 被管理的对象交给IoC容器,如何获取到IoC容器?(接口)
- IoC容器得到后,如何从容器中获取bean?(接口方法)
- 使用Spring导入哪些坐标?
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.10.RELEASE</version>
    </dependency>
然后创建配置文件applicationContext.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--  对象定义  <bean id="对象名" class="类全路径"/>-->
</beans>
在使用时,创建ApplicationContext接口实例,并从中取需要用的对象即可:
ApplicationContext ctxt = new ClassPathXmlApplicationContext("applicationContext.xml");
ctxt.getBean("定义时的id");
注意,bean定义时id属性在同一上下文中不能重复
DI入门
- 基于IoC管理bean
- Service中使用new形式创建的Dao对象是否保留?(否)
- service中需要的Dao对象如何进入到Service中?(提供方法)
- Service与Dao间的关系?
于是,将<bean/>标签改为闭合标签,在其中加入子标签<property/>,在其中设定对应的属性名和值,或者使用ref属性指定其他对象作为参数。
关于bean配置
- bean基础配置
格式:
<beans>
  <bean/>
  <bean></bean>
</beans>
属性: id:bean的id,使用容器可以通过id值获取对应的bean,在一个容器中id的值唯一 class:bean的类型,即配置的bean的全路径类名
范例:
<beans>
  <bean id="user" class="org.YD.pojo.User"/>
  <bean id="user2" class="org.YD.pojo.User"></bean>
</beans>
- bean别名配置
可以为bean增添name属性并且以空格分隔写多个名称作为bean的别名配置。
- bean作用范围配置
Spring默认的bean是单例的,即获取的都是同一个对象,但是可以通过添加scope属性为prototype,使每次获取时都为不同的对象。
bean默认为单例是为了减轻容器的压力,适合交给容器进行管理的bean如下:
- 表现层对象
- 业务层对象
- 数据层对象
- 工具对象
不适合交给容器进行管理的bean:
- 封装实体的域对象
bean的实例化
- 通过构造函数
bean本质上就是对象,创建bean使用构造方法完成,且默认调用的是无参构造函数
若类中没有只有含参构造函数而无参构造函数,Spring会报错。
- 通过静态工厂
可以通过调用静态工厂的方法获取对象,配置时,class属性填写静态工厂类名,额外添加factory-method属性配置获取对象的方法即可。
这种方式一般是为了兼容早期的遗留系统所使用的。
- 通过实例工厂
由于实例工厂在使用前需要先实例化工厂对象,然后通过工厂对象的方法创造对象,故需要先在配置中创建实例化的工厂对象,然后在需要的对象bean中,不使用class而是factory-bean属性指定实例化的工厂对象,然后用factory-method指定创造对象的方法。
同时,Spring提供了统一的实例工厂接口FactoryBean<>,实现接口后就不需要创建工厂对象的实例化而是直接用class属性指定实现的接口,Spring会自动调用接口中统一的方法生成对象。
另外,使用工厂生产的对象默认是单例的,而接口中的isSingleton方法可以用来指定是否为单例,false为非单例,true为单例。
bean的生命周期
- 生命周期:从创建到销毁的整体过程
在Spring中可通过init-method属性设置对象初始化的方法,通过destory-method属性设置对象销毁时执行的方法,另外可以在类中实现InitializingBean接口和DisposableBean接口来让Spring自动在初始化和销毁对象时调用相应的方法。
- 初始化容器
    - 创建对象
- 执行构造方法
- 执行属性注入(set操作)
- 执行bean初始化方法
 
- 使用bean
    - 执行业务操作
 
- 关闭/销毁容器
    - 执行bean销毁方法
 
- 容器关闭前才会触发bean的销毁操作
- 关闭容器方式:
    - 手工关闭容器,使用ConfigurableApplicationContext接口的close()方法
- 注册关闭钩子,使用ConfigurableApplicationContext接口的registerShutdownHook()方法
 
- 手工关闭容器,使用
关于bean标签的属性
<bean
  id="" bean的id
  name="" bean的别名
  class=""  bean类型,也可以用于指定对应的静态工厂类
  scop="singleton"  控制bean的实例数量
  init-method="init"  生命周期初始化方法
  destroy-method="destory"  生命周期销毁方法
  autowire="byType" 自动装配类型
  factory-method="" bean工厂方法,应用于静态工厂或实例工厂
  factory-bean="" 示例工厂bean
  lazy-init="true"  控制bean的延迟加载
/>
