Spring学习日记01:基础概念


Spring 学习日记01:基础概念

Spring是什么?

历史背景:简单的说就是以前Java用的EJB框架存在许多问题,不好用,一个大佬就写了本书叫<不用EJB进行JAVA开发>,后面blblbl产生了Spring。

SpringFramework是一个轻量级J2EE开发解决方案(框架)–Spring。目前最新版本为5.X。

Spring框架包含几个模块,例如 IOC,AOP,DAO,Context,ORM,WEB MVC 等。

Spring全家桶有哪些?

SpringFramework(依赖注入、事务处理、webapps、数据访问)

Spring MVC

SpringBoot

Spring Cloud(分布式、微服务)

Spring的优点

  • 轻量级
1.对于运行环境没有额外要求
    开源 tomcat resion jetty
2.代码移植性高
    不需要实现额外接口
  • JavaEE的解决方案

Java开发体系Java开发体系

  • 整合了设计模式(Design Pattern)
1、工厂
2、代理
3、模板
4、策略

Spring Framework做了什么?

支持控制反转(IoC) ,通过依赖注入(DI)来实现

支持面向切面编程(AOP)

控制反转(Inversion of Control)与工厂模式

所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。

举个例子。没有IoC之前,我们假设要设计一个 耳机、一个 手机(Phone),通常都是通过面向对象来new的方式。

public class AirPod{
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public void play(){
        System.out.println(this.name);
    }
}
public class Phone {
    private AirPod airPod;
    public Phone() {
        // 1.Phone是依赖于airPod的类
        this.airPod = new AirPod();
        this.airPod.setName("I am an airPod.");
    }
    public void play(){
        this.airPod.play();
    }
public static void main( String[] args )
    {
        // 1.Phone类依赖于AirPod这个具体类
        // 编译时如果没有AirPod这个类一定会出错
        Phone phone = new Phone();
        phone.play();
    }

这样做的弊端有:

1.如果AirPod还没有实现的情况,编译是通不过的。

2.假设我们以后新创建了一个类(AirPod2)以后。原来的代码都是固定死的,不易进行代码更新维护。

一种简单的处理方案:

通过接口来降低手机类与耳机类的耦合,这就算一种IoC的思想:使用 抽象 的 , 而不使用 具体 的。设计一个接口类。

public interface IEarPhone
{
    void play();
    void setName(String name);
}
public class AirPod implements IEarPhone {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public void play(){
        System.out.println(this.name);
    }
}
public class Phone {
    private IEarPhone airPod;
    public Phone() {
        // 2.此时Phone类不再依赖于接口IEarPhone,但是new AirPod依然依赖AirPod
        this.airPod = new AirPod();
        this.airPod.setName("I am an airPod.");
    }
    public void play(){
        this.airPod.play();
    }
}

但是目前,如果AirPod还没有实现的情况,编译还是通不过的。

现在我们就要谈到一个重要的东西——工厂模式。

工厂模式

概念:工厂方法模式基于”输入”,应用在超类和多个子类之间的情况,这种模式将创建对象的责任转移到工厂类,通过工厂类的工厂方法来创建对象。

好处:1.面向接口编程,体现了面向对象的思想;2.将创建对象的工作转移到了工厂类,解耦合;

现在用工厂模式来对手机与耳机的关系进行操作代价就小很多了。

// 静态工厂:用于创造实例并返回实例的方法。使用时不需要实例化工厂
public class BeanFactory {
    public static IEarPhone getEarPhone(){
        return new AirPod();
    }
}

但是!!!目前,如果AirPod还没有实现的情况,编译还是通不过的。

public class Phone {
    private IEarPhone airPod;
    public Phone() {
        // 3.使用静态工厂,Phone类不再依赖于AirPod,而BeanFactory依赖于AirPod
        this.airPod = BeanFactory.getEarPhone();
        this.airPod.setName("I am an airPod.");
    }
    public void play(){
        this.airPod.play();
    }
}

所以我们要利用反射的技术了

工厂模式+(配置+反射)-》DI (Dependecy Injection)

首先创建一个配置文件bean.properties(其实还可以使用xml形式配置)

airPod=cn.silverCorridors.AirPod

然后在工厂类中

public class BeanFactory {
    private static Properties props;
    static {
        try{
            props = new Properties();//Properties被替换的可能性极小
            InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
            props.load(in);
        } catch (IOException e) {
            throw new ExceptionInInitializerError("Cannot find bean.properties");
        }
    }
    
    // 通用工厂
    public static Object getBean(String beanName){
        Object bean = null;
        try{
            String beanPath = props.getProperty(beanName);
            bean = Class.forName(beanPath).getDeclaredConstructor().newInstance();
        }catch (Exception e){
            e.printStackTrace();
        }
        return bean;
    }
}

此时Phone中的工厂就可以不用在依赖于AirPod啦

public class Phone {
    private IEarPhone airPod;
    public Phone() {
        // 4.静态工厂+配置文件+反射,BeanFactory不依赖于AirPod,但是运行时要求AirPod存在
        this.airPod = (IEarPhone) BeanFactory.getBean("airPod");
        this.airPod.setName("I am an airPod.");
    }
    public void play(){
        this.airPod.play();
    }
}

通过这种方式,只要使用配置文件的方式就即时没有AirPod这个类也可以编译通过了。

工厂模式的意义

使用者只依赖于工厂类,而不依赖于资源

通过配置+反射,工厂类也可以不依赖于资源,只需要在运行时有资源即可。

Spring总体学习模块

Spring总体学习模块

典型的Spring支持的Web三层架构

mokuai


文章作者: 银色回廊
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 银色回廊 !
评论
  目录