Spring概念及IOC使用

Spring概述

1. Spring概念

Spring是分层的JavaSE/EE应用full-stack轻量级开源框架,以IOC(inverse Of Control,反转控制)和AOP(Aspect Oriented Programming,面向切面编程)为内核,提供了展示层SrpingMVC和持久层SpringJDBC以及业务层事务管理等众多企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,主键成为使用最多的JavaEE企业级应用开发框架。

2017 年 9 月份发布了 spring 的最新版本 spring 5.0 通用版(GA)

 

2. Spring的优势

  1. 方便解耦,简化开发

通过Spring提供的IOC容器,可以将对象间的依赖关系交由Spring进行控制,避免硬编码所造成的过程程序耦合。用户也不必再为单例模式类、属性文件解析等浙西很底层的需求编写代码,从而更专注于上层的应用。

  1. AOP编程的支持

通过Spring的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应对。

  1. 声明式事务的支持

可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事物的管理,提高开发的效率和质量。

  1. 方便程序的测试

可以用非容器依赖的编程方式进行所有测试工作,测试不再是昂贵的操作,而是随手可 做的事情。

  1. 方便集成各种优秀框架

Spring 可以降低各种框架的使用难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz 等)的直接支持。

  1. 降低 JavaEE API 的使用难度

Spring 对 JavaEE API(如 JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些 API 的 使用难度大为降低。

  1. Java 源码是经典学习范例

Spring 的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对 Java 设计模式灵活运用以 及对 Java 技术的高深造诣。它的源代码无意是 Java 技术的最佳实践的范例。

3. Spring体系结构

Core Container:对象容器

         Beans,Core,Context,SpEL:Map对象,可以通过解耦的方式获取对象。

 

IOC产生背景

1. 程序耦合:程序之间存在依赖关系

         包括:类之间的耦合

                   方法间的耦合

三层架构实现的项目,耦合性太高。

 

程序解耦:降低程序间的依赖关系

         开发中做到:编译期不依赖,运行时才依赖。

         类之间解耦思路:

    1. 通过反射创建对象,而避免使用new关键字
    2. 通过读取配置文件中的全限定类名,来获取要创建对象的类名

2. IOC解决程序耦合

    IOC(Inversion of Control, 控制反转)把自主创建对象(new对象)的权利交由框架或工厂,框架通过注入的依赖进行依赖查找,通过非面向对象编程的方式实现对象的创建,减少程序的耦合。

使用步骤:

  1. 创建容器配置文件。
    <?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="AccountService" class="com.spring.two.service.AccountServiceImpl"></bean>
        <bean id="AccountDao" class="com.spring.two.dao.AccountDaoImpl"></bean>
    </beans>
  2. 通过ApplicationContext获取对象
    public class IOCTest {
        public static void main(String[] args) {
            ApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
            Account account=new Account();
    
            AccountService service=context.getBean("AccountService", AccountService.class);
            service.saveAccount(account);
        }
    }

IOC细节

1. IOC相关类的继承结构

2. ApplicationContext容器接口

实现了BeanFactory、ResourceLoader等接口。

 

ApplicationContext的实现类:通过配置内容创建容器。

ClassPathXmlApplicationContext: 加载类路径下的配置文件,创建容器;

FileSystemXmlApplicationContext: 加载磁盘路径下的配置文件,创建容器;

AnnotationConfigApplicationContext: 读取注解,创建容器;

 

ApplicationContext接口 VS BeanFactory接口:

ApplicationContext:适用于单例对象

         立即加载(默认):读取完配置文件后,创建配置文件中的所有对象。对象被调用时,返回已创的对象。

         可以通过配置文件,改变对象的创建模式(单例,多例)。

BeanFactory:适用于多例对象

         延迟加载:当对象d被需要时,通过配置文件,创建对象。

 

3. <bean>标签:用于容器创建对象

在xml中配置类标识和全限定类名的关系,ApplicationContext容器通过加载<bean>标签,以非OOP的方式创建对象。

 

属性:

         id:对象在容器中的唯一标识。

         class:对象的全限定类名

         scope:对象的作用范围。

         init-method:初始化方法名

         destroy-method:销毁方法名

子标签:

         <constructor-age>:通过构造方法,注入依赖

         <property>:通过set方法,注入依赖

 

scope属性:容器对象的作用范围。

         a)singleton:默认的,创建单例对象。

生命周期:

         出生:立即加载。容器一旦加载配置文件,对象就随之创建;

         存活:只要容器存活,对象就存活;

         死亡:容器销毁,对象也死亡。

         b) prototype: 创建多例对象。

生命周期:

         出生:对象被使用时,由Spring框架创建;

         存活:对象使用过程中一直存活;

         死亡:对象长时间不使用并没有别的对象引用时,由垃圾的回收期回收。

         c)request: 作用于web应用的一次请求范围,将对象存储到request域中

         d)session:作用于web应用的一次会话范围,将对象存储在session域中。

         e)global-session:作用于集群环境的会话范围。

集群环境:同一IP的所有服务器中,一次会话中共享数据。

通过bean标签创建对象的三种方式:

a) <bean id=””, class=””>: 使用类的默认构造函数创建对象,并存入Spring容器。

                 如果类中没有默认构造函数,则对象无法创建

b) <bean id=””, class=”全限定类名”, factory-method=”方法”>:使用工厂的方法创建对象(某个类的方法创建对象,并存入core contrainer)

c) <bean id=””, class=”全限定类名”, factory-mehtod=”方法”>: 使用工厂的静态方法创建对象(某个类的静态方法创建对象,并存入spring容器)

 

4. 注入依赖

Spring通过IOC以非OOP的方式创建对象,降低程序间的耦合。

并且Spring维护类之间的依赖关系,即当类需要使用其他类的对象时,由Spring提供所依赖的对象,我们只需要在配置文件中说明依赖的关系,这就称为依赖注入。

 

依赖注入的类型:

  1. 基本类型和String:String会转成需要的基本类型
  2. Bean类型(在配置文件中或注解中配置过的Bean类)
  3. 复杂类型:数组、List、Set、Map、Properties等

 

依赖注入的方式:

  1. 构造函数+<constructor-org>子标签
    1. 在类中,依赖通过类构造函数的参数赋值。
    2. 在配置文件中,通过<constructor-org>标签注入依赖:

属性:type: 注入数据的类型

           index:注入数据的索引

           name: 注入数据的参数名

           value:要注入的基本类型或String类型的数据。

           ref:要注入的bean对象。包括注解配置的或xml配置的bean对象

构造函数方法注入:

<bean id="AccountService2" class="com.spring.two.service.AccountServiceImpl2">
        <constructor-arg name="name" value="neo"></constructor-arg>
        <constructor-arg name="age" value="18"></constructor-arg>
        <constructor-arg name="birthday" ref="birthday"></constructor-arg>
</bean>
<bean id="birthday" class="java.util.Date"></bean>

构造函数:
public AccountServiceImpl2(String name, int age, Date birthday) {
        this.name = name;
        this.age = age;
        this.birthday = birthday;
}

优点:Spring创建bean对象时,依赖都被注入,否则无法创建成功

         缺点:改变了bean对象实例化的方式,所需依赖必须注入,即使是用不到时

2.set方法+<property>标签

    1. 在类中,依赖通过setXXX方法赋值
    2. 配置文件中,通过<property>标签注入依赖:

属性:

name: 注入数据的set方法名

value:注入的基本类型或String类型数据

ref:注入的bean类型数据。

<!--    set方法注入-->
<bean id="AccountService2"  class="com.spring.two.service.AccountServiceImpl2">
        <property name="name" value="neo"></property>
        <property name="age" value="17"></property>
        <property name="birthday" ref="birthday"></property>
</bean>
<bean id="birthday" class="java.util.Date"></bean>

优点:创建对象时,没有明确的依赖限制,直接使用默认构造函数创建;

         缺点:如果对象的某个依赖必须存在,通过set方式无法满足此要求。

posted @ 2021-12-27 22:16  言思宁  阅读(113)  评论(0)    收藏  举报