Spring5(25) —— 回顾和总结


  • spring就是一个轻量级的、通过配置文件实现了控制反转(IOC)和面向切面编程(AOP)两种思想的免费的开源框架
  • 所以学习spring,我们重点就是理解控制反转(IOC)和面向切面编程(AOP)两种思想

1.理解IOC

    IOC(Inversion of Control,控制反转):控制指的就是原来我们程序中出现了类与类之间的引用的情况,即一个类为了实现功能,需要使用另一个类,即A类依赖于B类,都是A类直接new一个B类的对象,new对象的过程是程序自己控制的;反转指得不是让B对象自己new好了送到A哪里去,而是借助于"第三方"(即IOC容器)实现具有依赖关系的对象属性的注入,从而实现依赖双方之间的 解耦/降低耦合度

1.案例

    我们实现javaweb的操作流程就是"数据库–Dao–service–servlet–JSP",我们就抽出Dao–service两层来讲一下

//dao接口设计
package com.thhh.dao;

public interface IocDao {
    public void daoMethod(); //一个用来测试的接口
}
//dao接口实现
package com.thhh.dao;

public class IocDaoImpl implements IocDao {
    public void daoMethod() {
        System.out.println("DAO层的操作");
        System.out.println("数据库中的数据");
    }
}
//service接口设计
package com.thhh.service;

public interface IocDaoService {
    public void serviceMethod();//业务类接口,这里就跟dao一样
}

//service接口实现
package com.thhh.service;

import com.thhh.dao.IocDao;
import com.thhh.dao.IocDaoImpl;

public class IocDaoServiceImpl implements IocDaoService{
    private IocDao iocDao = new IocDaoImpl();  //创建一个接口.
    public IocDao getIocDao() {
        return iocDao;
    }
    public void setIocDao(IocDao iocDao) {
        this.iocDao = iocDao;
    }
    public void serviceMethod() {
        System.out.println("service层的操作");
        iocDao.daoMethod();//调用接口方法
    }
}
//测试
import com.thhh.service.IocDaoService;
import com.thhh.service.IocDaoServiceImpl;
import org.junit.Test;

public class MyTest {
    @Test
    public void test01(){
        IocDaoService iocDaoService = new IocDaoServiceImpl();
        iocDaoService.serviceMethod();
    }
}

在这里插入图片描述
在这里插入图片描述

    很明显,在我们service层的方法中肯定是在调用dao层中的对象提供的方法来获取数据返回给controller层的,但是由于service层需要调用dao层接口接口的方法才能获取到数据,所以我们不得不new一个对象保存在service层内部
在这里插入图片描述

    当dao层和service层的类多起来的时候,我们就会发现,service层中的所有类都在依赖dao层中的类,那么一旦我们修改或删除某一个dao层的类,service的维护可想而知,这就是层与层之间、类与类之间耦合性太大带来的问题

    显而易见,解决办法就是降低耦合性,上图都说了,调用方法的耦合性是不可避免的,那么可以避免的就是new实体类的那一步了

    IOC的思想就是通过收缴所有new对象的操作权限(就是不准程序里面new对象),使得层与层之间、类与类之间的耦合性降低(即通过限制new对象的操作降低一个类对另一个类的使用程度,一个类使用其他类越少,两个类的耦合度就越小,修改起来代价就小,修改就越方便)

    注意:不是没有耦合性,而是降低耦合;没有耦合性那各个模块就是相互独立的,你用你的,我用我的,就没有代码复用的可能了
在这里插入图片描述
    但是现在明显的问题就是:怎么实例化这个接口对象?
    IOC给出的实现方法就是使用IOC容器,IOC容器就是我们写的applicationContext.xml文件,我们在使用的时候按照"new ClassPathXmlApplicationContext(“applicationContext.xml”);" 就实例化了容器对象,即ApplicationContext对象,然后我们就可以从容器中获取对象了

<?xml version="1.0" encoding="UTF8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">
    
    <bean id="IocDaoImpl" class="com.thhh.dao.IocDaoImpl"/>
    <bean id="IocDaoServiceImpl" class="com.thhh.service.IocDaoServiceImpl">
        <property name="iocDao" ref="IocDaoImpl"/>
    </bean>
</beans>

    IOC容器可以实现的前提就是,项目中的所有对象,都必须由IOC容器管理,你不能自己偷偷new一个对象,否则IOC就可能不能为你的引用对象实现自动注入

在这里插入图片描述

//测试
import com.thhh.service.IocDaoService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    @Test
    public void test01(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        IocDaoService iocDaoServiceImpl = context.getBean("IocDaoServiceImpl", IocDaoService.class);
        iocDaoServiceImpl.serviceMethod();
    }
}

在这里插入图片描述
在这里插入图片描述
    总结一下spring实现IOC的方式:IOC的做法就是将一个类对另一个类的关联从类与接口和该接口的实现类的关系,减少到类与接口的关系;需要引用的类只需要有一个接口定义和接口属性的set方法,IOC容器就能为它注入一个它希望使用的这个接口的某个实现类的实例供它使用(spring实现IOC的做法就是在配置文件中通过bean节点的property子节点的ref属性实现的)

在这里插入图片描述

    按照IOC的思想,在使用spring的程序中不能使用new来创建对象,每定义好一个class类,我们就需要去spring配置文件中将它装配上;类与类之间的引用,通过bean节点的property子节点的ref属性实现,实现了容器中的bean自动注入的效果,使得在类中要引用另一个类,我们只需要知道它的接口,不需要知道它的具体实现类,这就降低了类与类之间的耦合

    如果想要换一个实现类,也不用修改源代码,只要新的实现类已经装配到了spring容器中,去配置文件中修改对应的bean的property的ref属性即可

帮助理解的链接

    下面的3个链接基本都是有理论有代码的,脱开代码讲理论都是耍流氓


2.DI

    依赖注入(Dependency Injection)
    2004年,Martin Fowler探讨了同一个问题,既然IOC是控制反转,那么到底是“哪些方面的控制被反转了呢?”,经过详细地分析和论证后,他得出了答案:“获得依赖对象的过程被反转了”

    控制被反转之后,获得依赖对象的过程由自身管理变为了由IOC容器主动注入。于是,他给“控制反转”取了一个更合适的名字叫做“依赖注入(Dependency Injection)”
    他的这个答案,实际上给出了实现IOC的方法:注入。所谓依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中

    所以,依赖注入(DI)和控制反转(IOC)是从不同的角度的描述的同一件事情,就是指通过引入IOC容器,利用依赖关系注入的方式,实现对象之间的解耦

    再来重新理解一遍DI

  • 依赖:就是A类要实现功能,但是需要使用到B类的某个方法,那么就称A类依赖于B类
  • 注入:就是在IOC容器被获取的时候,所有装配在容器中的对象都会被实力化,而一个类中的依赖,由于在IOC容器中已经装配了对应的对象属性的映射,所以对象属性的值已经被IOC容器注入了,我们可以直接使用,而不用再自己new该对象属性了

3.注意区分

    IOC是一种思想,一种解决类与类之间引用解耦问题的思想,而spring是一种实现IOC的方式,一种框架,它实现IOC的方式就是使用配置文件


2.理解AOP

    AOP是一种思想,是一种横向增强系统功能的编程思想,其实现原理就是Gof23中的动态代理模式
    而spring框架实现的AOP的方式就是通过配置文件来实现动态代理模式

复习链接
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值