Spring:全功能栈的应用程序框架第一天

【Spring:全功能栈的应用程序框架第一天】

1   Spring框架的介绍

1.1  目前遇到的问题

1. 目前使用mybatis + servlet的时候,书写的代码业务层相对比较的麻烦(获取SqlSession、获取Mapper)

2. 目前书写的代码层和层之间的耦合性比较高(Controller调用Service,Service调用Mapper,如果Service发生了改变,需要修改Controller的代码)

3. 目前书写的代码后期的扩展性比较低(在给项目的功能进行升级的时候,需要修改源代码)

4. 整体项目中事务的处理机制(对数据库的增删改需要自己提交、回滚事务)

1.2  解决的方案

使用Spring 解决。

Spring 是解决了业务层和其他各层之间的耦合(高内聚、低耦合)。

1.3  Spring 框架简介

l  Spring, 春天. Spring框架在开发中的角色是用于管理其他的框架和对象. 换句话说, Spring可以使已有的技术更好用.

简单来说,Spring是一个容器框架,可以帮我们去管理对象!

Jar包和源码的下载地址

n  https://github.com/spring-projects/spring-framework/tags

n  https://repo.spring.io/libs-release-local/org/springframework/spring/

l  学习Spring的主要内容:

n  IOC / DI: 控制反转 / 依赖注入

n  AOP: 面向切面编程

n  TX:事务管理

1.4  介绍Spring Framework Runtime

 

 

 

l  Test

对应spring-test.jar. Spring提供的测试工具, 可以整合JUnit测试, 简化测试环节.

l  Core Container

Spring的核心组件, 包含了Spring框架最基本的支撑.

Beans, 对应spring-beans.jar. Spring进行对象管理时依赖的jar包.

Core, 对应spring-core.jar, Spring核心jar包.

Context, 对应spring-context.jar, Spring容器上下文对象.

SpEL, 对应spring-expression.jar, Spring表达式语言.

l  AOP

面向切面编程, 对应spring-aop.jar.

l  Data Access

Spring对数据访问层的封装

JDBC, 对应spring-jdbc.jar. Spring对jdbc的封装, 当需要使用spring连接数据库时使用. spring-jdbc.jar需要依赖spring-tx.jar.

Transactions, 对应spring-tx.jar. 事务管理

ORM, 对应spring-orm.jar. spring整合第三方orm框架需要使用的jar包, 例如Hibernate框架.

l  Web

Spring对javax下的接口或类做的扩展功能.

spring-web.jar, 对Servlet, filter, Listener等做的增强.

spring-webmvc.jar, 实际上就是SpringMVC框架. 需要依赖spring环境和spring-web.jar.

 

不论我们使用Spring框架的哪个功能,都必须先导入Spring Core Container的4个包!

Spring是一个容器框架,这个容器具体点来说,可以理解为是IOC!

2   SpringIOC的介绍和学习

目前我们学习Spring框架,就学:

  1. IOC(DI)(控制反转,Inversion Of Control,依赖注入,Dependency Injection)
  2. AOP(面向切面编程,Aspect Oriented Programming)
  3. 事务管理(Transaction,tx)

2.1  SpringIOC的介绍

问题:

使用MVC的结构体系来完成后端功能代码的开发后,在一定程度上降低了代码的冗余,但是层与层之间的耦合性过高,造成代码升级维护特别麻烦。

比如,业务层某个类文件需要替换为新的类文件,那么,控制层所有调用该业务类的代码需要全部修改为调用新的业务类.

解决:

将层与层对象之间的关系进行解耦,由直接变为间接.

实现:

SpringIOC.

作用:

实现了代码层与层之间的解耦.

2.2  SpringIOC的原理

2.2.1  之前的方式

 

 

 

正常来说:Servlet调用Aservice类中的方法,Service再调用Mapper操作数据库。

当需要对项目升级,我们编写了Bservice,那就需要Servlet中创建Service对象的代码。整个项目中,可能有许多地方的Servlet都需要修改这部分代码。这就比较麻烦了!

好的一点是,我们的A、B两个Service实现了接口,这样还不需要去修改Servlet中具体方法的调用。(体会用接口编程的好处!多态!)

解决:

Servlet需要用到Service的对象,不要通过new的方式来获取,如果有个容器能直接给我们就好了。(前提是这个容器中能有我们想要的对象)

2.2.2  使用SpringIOC后的方式

 

 

 

总结:将Service的对象交给了SpringIOC容器帮我们去管理,Servlet要使用Service的对象,不需要自己创建,只需要问容器要即可。

这样获取对象的方式就由自己直接创建,变成了问容器要,也就是间接获取。

2.3  SpringIOC的基本使用

2.3.1  作用

IOC将耦合性非常高的对象进行解耦.也就是帮我们去创建、管理类的对象。

2.3.2  时机

什么时候使用IOC对对象进行解耦是一个主观问题,应当根据代码的结构以及功能的需求进行分析,然后决定哪些对象之间需要使用IOC解耦,也就说哪些对象应该由我们自己在代码中new创建,变为由SpringIOC容器帮助我们创建,我们获取使用即可。

一般情况下,在MVC代码结构中,会将Servlet和Service之间解耦,Service和Mapper之间解耦。也就是将Service和Mapper层中的对象都交给SpringIOC帮我们管理即可!

3   SpringIOC创建对象的方式

3.1  概述

Spring创建对象有两种方式:

  1. 在Spring的配置文件中配置bean标签后,通过反射去创建对象
  2. 使用FactoryBean(工厂bean)的方式去创建

3.2  配置bean标签的方式

在Spring的配置文件中配置好bean标签,然后class属性用来指定类的全路径,Spring容器在启动的时候就会根据类的全路径使用反射去创建对象,然后id属性就是该对象的引用!

3.3  通过FactoryBean的方式

FactoryBean是工厂bean,我们可以造一个制造某个对象的工厂,然后让工厂帮我们去创建对象。

说明:这种方式我们一般不用,是框架内部比较爱用。

// 我们自定义类去实现SpringFactoryBean接口,泛型就是该工厂要创建的对象
public class UserFactoryBean implements FactoryBean<User> {
    //Spring用来管理工厂创建的对象
   
@Override
    public User getObject() throws Exception {
        return new User();
    }

    //获取该对象的类型
   
@Override
    public Class<?> getObjectType() {
        return User.class;
    }
}

 

<!--
   
配置工厂Bean,虽然这里配置了bean标签,而且class指定的是UserFactoryBean类的全路径
   
Spring并不是帮我们去创建了UserFactoryBean类的对象,
   
而是帮我们管理了UserFactoryBean中创建出来的对象。
-->
<bean id="userFactoryBean" class="com.bjsxt.test.UserFactoryBean"></bean>

 

4   DI依赖注入

4.1  概述

DI是Dependency Injection,也就是依赖注入的意思。

依赖:比如,Servlet要调用Service中的方法,那我们就说Servlet是依赖service的,Service要调用Mapper中的方法,那我们就说Service是依赖Mapper的。

注入:就是给某个属性赋值,也就是给某个依赖的属性赋值。

依赖注入就是给某个类依赖的属性赋值。

4.2  注入的两种方式

DI注入有两种方式:

  1. 有参构造器注入:通过构造器给属性赋值
  2. set方法注入:通过set方法给属性赋值

4.3  有参构造注入

有参构造注入就是Spring容器在创建某个类的对象时,通过它的有参构造器给对象的属性赋值。

public class Car {
    private String brand;
    private String color;

    public Car() {
    }

    public Car(String brand, String color) {
        this.brand = brand;
        this.color = color;
    }

 

 

public class User {
    private Integer id;
    private String name;
    private String sex;
    private Car car;

    public User() {
    }

    public User(Integer id, String name, String sex, Car car) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.car = car;
    }

 

 

<!--
   
构造注入:通过构造器的方式给属性赋值
-->
<bean id="car" class="com.bjsxt.pojo.Car">
    <constructor-arg name="brand" value="奔驰"></constructor-arg>
    <constructor-arg name="color" value="黑色"></constructor-arg>
</bean>

<bean id="user" class="com.bjsxt.pojo.User">
    <constructor-arg name="id" value="1"></constructor-arg>
    <constructor-arg name="name" value="张三"></constructor-arg>
    <constructor-arg name="sex" value=""></constructor-arg>
    <!-- ref 就表示引用哪个对象,ref的值是某个对象在Spring容器中的id-->
   
<constructor-arg name="car" ref="car"></constructor-arg>
</bean>

 

public static void main(String[] args) {
    ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
    User user = (User) ioc.getBean("user");
    System.out.println(user);
}

4.4  set方法注入

<!--
    set
方法注入:根据调用该属性对应的set方法给属性赋值
-->
<bean id="car2" class="com.bjsxt.pojo.Car">
    <property name="brand" value="宝马"></property>
    <property name="color" value="白色"></property>
</bean>

<bean id="user2" class="com.bjsxt.pojo.User">
    <property name="id" value="2"></property>
    <property name="name" value="李四"></property>
    <property name="sex" value=""></property>
    <property name="car" ref="car2"></property>
</bean>

4.5  自动装配

从上面的两种注入方式中我们看到,给某个类的属性依赖注入的时候,我们需要配置依赖关系,如果类多的话,这个还是比较麻烦的。能不能我们每个类只做些简单配置,不要再配置依赖关系,然后让Spring容器帮我们自动去给属性赋值呢?

当然是可以的,这就是Spring提供的自动装配功能!

posted @ 2020-12-30 20:51  LesterLin  阅读(34)  评论(0)    收藏  举报