Spring框架个人笔记(IOC)

Spring

是什么

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

优点

  1. 面向接口编程,而不是针对类编程。Spring框架将使用接口的复杂度降低到零。
  2. Spring是一个开源免费的框架(容器)
  3. Spring是一个轻量级的、非入侵式的框架。
  4. 控制反转(IOC),面向切面编程(AOP)
  5. 支持事务的处理,对框架整合的支持

Spring的作用

  1. 方便解耦、简化开发 通过 Spring提供的 IoC容器,可以将对象间的依赖关系全部交给Spring容器进行管理,避免硬编码所造成的过度程序混乱和耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可 以更专注于上层的应用。
  2. 对AOP编程的支持 通过 Spring的 AOP 功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过 AOP 轻松应付。
  3. 对声明式事务的支持 可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理, 提高开发效率和质量。
  4. 方便程序的测试 ,可以用非容器依赖的编程方式进行测试工作。
  5. 降低对各类框架集成的难度,Spring可以降低各种框架的使用难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz 等)的直接支持。
  6. 降低 JavaEE API的使用难度 Spring对 JavaEE API(如 JDBC、JavaMail、远程调用等)进行了封装,使这些 API 的使用难度降低。

Spring体系结构

在这里插入图片描述

上图是Spring框架的体系结构,这些组件被分为多个模块,分别是Core Container(核心容器),AOP(Aspect Oriented Programming (面向切面编程))、数据层访问集成(Data Access/Integratioin),web层整合及Test单元测试组件。

  1. Core模块是Spring的核心容器,它实现了IOC容器模式,提供了Spring框架的基础功能。此模块中包含的BeanFactory类是Spring的核心类,负责JavaBean的配置与管理。它采用Factory工厂模式实现了IOC即依赖注入。
  2. Context模块继承BeanFactory(或者说Spring核心)类,并且添加了事件处理、国际化、资源装载、透明装载、以及数据校验等功能。它还提供了框架式的Bean的访问方式和很多企业级的功能,如JNDI访问、支持EJB、远程调用、集成模板框架、Email和定时任务调度等。
  3. Spring的AOP模块可以通过事务管理可以使任意Spring管理的对象AOP化。Spring提供了用标准Java语言编写的AOP框架,它的大部分内容都是基于AOP联盟的API开发的。它使应用程序抛开EJB的复杂性,但拥有传统EJB的关键功能。
  4. DAO是DataAccessObject的缩写,DAO模式思想是将业务逻辑代码与数据库交互代码分离,降低两者耦合。通过DAO模式可以使结构变得更为清晰,代码更为简洁。DAO模块提供了JDBC的抽象层,简化了数据库厂商的异常错误(不再从SQLException继承大批代码),大幅度减少代码的编写,并且提供了对声明式事务和编程式事务的支持。
  5. Web模块建立在Context基础之上,它提供了Servlet监听器的Context和Web应用的上下文。对现有的Web框架,如JSF、Tapestry、Structs等,提供了集成。Structs是建立在MVC这种公认的好的模式上的,Struts在M、V和C上都有涉及,但它主要是提供一个好的控制器和一套定制的标签库上,也就是说它的着力点在C和V上,因此,它天生就有MVC所带来的一系列优点,如:结构层次分明,高可重用性,增加了程序的健壮性和可伸缩性,便于开发与设计分工,提供集中统一的权限控制、校验、国际化、日志等等。
  6. Test模块提供对使用JUnit和TestNG来测试Spring组件的支持,它提供一致的ApplicationContext并缓存这些上下文,它还能提供一些mock对象,可以独立地测试代码。

什么是程序的耦合

耦合性(Coupling),也叫耦合度,是模块之间关联程度的度量。耦合的强弱取决于模块间接口的复杂性、模块间的耦合度是指模块之间的依赖关系,包括控制关系、调用关系、数据传递关系。

各个模块之间的联系越多,其耦合性就越强,同时表明其独立性越差( 降低耦合性,可以提高其独立扩展性)。在软件工程中,耦合指的就是对象之间的依赖性。

对象之间的耦合越高,维护成本越高。因此对象的设计应该使类和模块之间的耦合最小。软件设计中通常用耦合度和内聚度作为衡量模块独立程度的标准。划分模块的一个 准则就是高内聚低耦合。

它有如下分类:

(1) 内容耦合:当一个模块直接修改或操作另一个模块的数据时,或一个模块不通过正常入口而转入另一个模块时,这样的耦合被称为内容耦合。内容耦合是最高程度的耦合,应该避免使用。

(2) 公共耦合:两个或两个以上的模块共同引用一个全局数据项,这种耦合被称为公共耦合。在具有大量公共耦合的结构中,确定究竟是哪个模块给全局变量赋了一个特定的值是十分困难的。

(3) 外部耦合 :一组模块都访问同一全局变量而不是同一全局数据结构,而且不是通过参数表传 递该全局变量的信息,则称之为外部耦合。

(4) 控制耦合:一个模块通过接口向另一个模块传递一个控制信号,接受信号的模块根据信号值而进 行适当的动作,这种耦合被称为控制耦合。

(5) 标记耦合:若一个模块 A 通过接口向两个模块 B 和 C 传递一个公共参数,那么称模块 B 和 C 之间 存在一个标记耦合。

(6) 数据耦合:模块之间通过参数来传递数据,那么被称为数据耦合。数据耦合是最低的一种耦合形 式,系统中一般都存在这种类型的耦合,因为为了完成一些有意义的功能,往往需要将某些模块的输出数据作为另一些模块的输入数据。

(7) 非直接耦合:两个模块之间没有直接关系,它们之间的联系完全是通过主模块的控制和调用来实现的。

总结

耦合是影响软件复杂程度和设计质量的一个重要因素,在设计上应该采用以下原则:

内聚与耦合

如果模块间必须存在耦合,就尽量使用数据耦合,少用控制耦合,限制公共耦合的范围,尽量避免使用内容耦合。 内聚标志一个模块内各个元素彼此结合的紧密程度,它是信息隐蔽和局部化概念的自然扩展。内聚是从功能角度来度量模块内的联系,一个好的内聚模块应当恰好做一件事。它描述的是模块内的功能联系。

耦合是软件结构中各模块之间相互连接的一种度量,耦合强弱取决于模块间接口的复杂程度、进入或访问一个模块的点以及通过接口的数据。 程序讲究的是低耦合,高内聚。就是同一个模块内的各个元素之间要高度紧密,但是各个模块之间的相互依存度却要不那么紧密。 内聚和耦合是密切相关的,同其他模块存在高耦合的模块意味着低内聚,而高内聚的模块意味着该模块同其他模块之间是低耦合。所以在进行软件设计时,应力争做到高内聚,低耦合。

耦合的通俗解释:

指程序之间的依赖关系,包括:类之间的依赖关系、方法间的依赖关系

Spring快速入门

新建maven工程

新建一个名为spring的maven工程并导入以下依赖

<dependencies>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.9.RELEASE</version>
    </dependency>
    <!-- 提供get&set 和构造方法的依赖 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
    </dependency>
    <!-- 单元测试依赖 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>

创建实体对象

新建一个User对象并提供成员变量和get&set方法

@Data //提供get&set方法的注解
@ToString //提供toString方法的注解
public class User {
   
    private String username;
    private Integer age;
    private String sex;
    private String height;
}

编写配置类

在xml配置文件里把User对象交给spring工厂去管理

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    
	<!--  以上是spring头文件,必须导入  -->

    
    <!-- 在配置文件里给User对象赋值,交给spring容器去托管对象 -->
    <bean id="user" class="com.spring.practice.User">
        
        <!-- 以下使用set方法注入属性: name为成员变量名称,value为属性值-->
        <property name="username" value="Trump"/>
        <property name="age" value="3"/>
        <property name="sex" value="不男不女"/>
        <property name="height" value="150cm"/>
        
    </bean>
</beans>

测试

使用ClassPathXmlApplicationContext读取配置类数据,并调用工厂方法获取User对象里的属性

public class SpringTest {
   

    @Test
    public void testUser() {
   
        //创建一个Spring容器对象
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        //获取bean配置的id值User字节码对象
        User user = context.getBean("user",User.class);
        System.out.println(user);
    }
}

测试结果:

在这里插入图片描述

Sping常用API

ApplicationContext接口

org.springframework.context.ApplicationContext接口表示Spring的IOC容器,负责实例化、配置和组装bean。容器通过读取配置文件中配置的元数据来获取关于对象的实例化、配置和组装哪些对象的说明。配置元数据以XML形式、Java注释或Java代码表示。它允许您表示组成应用程序的对象以及这些对象之间的丰富相互依赖关系。

ApplicationContext接口的几个实现类由Spring提供,常见的做法是创建ClassPathXmlApplicationContext或者FileSystemXmlApplicationContext实现类。虽然XML一直是定义配置元数据的传统格式,但是可以指定容器使用Java注释或代码替代XML形式作为元数据的配置,用法是提供少量XML配置以声明性地启用对这些附加元数据格式的支持。

下图显示了SpringIOC容器的流程。应用程序类与配置元数据组合,以便在ApplicationContext创建并初始化后将有一个完全配置和可执行的系统或应用程序。

在这里插入图片描述

ClassPathXmlApplicationContext

ClassPathXmlApplicationContext是ApplicationContext的子类,它可以加在类路径下的bean实例配置文件,用于根据配置文件获取对象实例,要求配置文件必须在类路径下,也只能读取在类路径下的配置文件。(比较常用的方式)

//创建容器获取对象的配置实例
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

//也可以采用父类new子类的方式。
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

FileSystemXmlApplicationContext

FileSystemXmlApplicationContext类也继承了ApplicationContext接口,它可以加载磁盘任意路径下的配置文件(必须有访问限权),但必须以绝对路径的方式。

例如:

ApplicationContext context = 				//指定系统绝对路径声明配置文件
        new FileSystemXmlApplicationContext("A:\\markdown-node\\spring\\conf\\bean.xml"); 

AnnotationConfigApplicationContext

AnnotationConfigApplicationContext类是用于读取注解进行容器元数据的配置,使用此类可以实现基于Java的配置类加载Spring的应用上下文。避免使用繁琐的配置文件进行配置。相比XML配置更加方便快捷。

ApplicationContext context = new 		//采用读取java配置类来初始化对象实例,替代了XML文件。
                   AnnotationConfigApplicationContext(AnnotationConfiguration.class);

基于xml的Spring配置

bean标签

从上面入门案例可以看出,bean标签用于管理对象,并创建对象实例设置对象的属性值,该标签的作用就是把对象放到容器中管理。

<!-- 格式↓↓↓ -->
<bean id="对象id" class="全限定类名" >
	<property name="成员变量" value="属性值"/>
    ...
</bean>

在 spring 配置文件中使用 bean 标签,标签里面添加对应属性就可以实现对象创建,在 bean 标签有很多属性,下面是常用的bean属性。

id属性

bean标签中的id属性为对象的唯一标识,用于在创建容器对象的时候指定此id。

例如:

//创建容器对象,指定配置文件名称
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
//指定配置文件中的id唯一标识,并获取User类的字节码对象
User user = context.getBean("user",User.class);
name属性

name属性和id属性类似,都是指定对象的唯一标识作为标记,如果两个都指定了唯一标识则都能生效,不同的标识id都可作为对象的实例化标志,例如

<!-- id和name属性相同的标识都可识别,如果不同则可以分别取值使用 --><
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值