当前位置: 首页 > news >正文

Spring基础

1 Spring

1.1 spring优点

  • spring是一个开源的免费框架
  • spring是一个轻量级、非入侵式的框架
  • 控制反转(IOC),面向切面
  • 支持事务的处理,对框架整合的支持!

总结一句话:Spring是一个轻量级的控制反转(IOC)和面向切面变成(AOP)的框架!!

1.2 spring组成

image-20210731223741215

1.3 拓展

在spring的官网有这个介绍,现代化java开发,说白了就是基于spring开发

image-20210731224007938

springboot

  • 是一个快速开发的脚手架,
  • 基于springboot可以快速开发单个微服务
  • 约定大于配置

springcloud

  • 基于springboot实现

现在大多数公司都在使用springboot进行快速开发使用,学习springboot的前提是完全掌握spring和springmvc!

spring起到承上启下的作用!!

弊端:spring发展太久之后违背了原来的理念,配置十分繁琐,人称"配置地狱"!!!!

2 IOC理论推导

使用spring之前

  1. userDao接口

    package com.wshy.Dao;
    
    /**
     * @author wshy
     * @data 2021/7/31
     **/
    public interface UserDao {
        void getUser();
    }
    
    
  2. userDaoImpl实现类

    package com.wshy.Dao;
    
    /**
     *
     * @title: UserDaoImpl
     * @Author: wshy
     */
    public class UserDaoImpl implements UserDao {
        @Override
        public void getUser () {
            System.out.println ("默认获取用户的数据");
        }
    }
    
  3. userService业务接口

    package com.wshy.Service;
    
    /**
     * @author wshy
     * @data 2021/7/31
     **/
    public interface UserService {
        void getUser();
    }
    
    
  4. userServiceImpl业务实现类

    package com.wshy.Service;
    import com.wshy.Dao.UserDao;
    import com.wshy.Dao.UserDaoImpl;
    
    /**
     *
     * @title: UserServiceImpl
     * @Author: wshy
     */
    public class UserServiceImpl implements UserService{
    
        private UserDao userDao = new UserDaoImpl ();
    
        @Override
        public void getUser () {
            userDao.getUser ();
        }
    }
    

    5.测试类

    import com.wshy.Service.UserService;
    import com.wshy.Service.UserServiceImpl;
    
    /**
     *
     * @title: MyTest
     * @Author: wshy
     */
    public class MyTest {
        public static void main (String[] args) {
    
            // 用户实际调用的是业务层,Dao层并不接触
            UserService userService = new UserServiceImpl ();
            userService.getUser ();
        }
    }
    
    

    6.结果打印

    image-20210731233847466

    此时,如果业务需求增加,需要增加一个mysql实现类,需要增加UserDaoMySqlImpl、UserServiceImpl

    着重看UserServiceImpl业务层实现类的new对象的操作,修改为private UserServiceMySqlImpl userDao = new UserServiceMySqlImpl ();

    package com.wshy.Dao;
    
    import com.wshy.Service.UserService;
    
    /**
     * @title: UserServiceMySqlImpl
     * @Author: wshy
     */
    public class UserServiceMySqlImpl implements UserService {
        @Override
        public void getUser () {
            System.out.println ("Mysql实现类");
        }
    }
    
    
    package com.wshy.Service;
    import com.wshy.Dao.UserDao;
    import com.wshy.Dao.UserDaoImpl;
    import com.wshy.Dao.UserServiceMySqlImpl;
    
    /**
     *
     * @title: UserServiceImpl
     * @Author: wshy
     */
    public class UserServiceImpl implements UserService{
    
        //private UserDao userDao = new UserDaoImpl ();
        private UserServiceMySqlImpl userDao = new UserServiceMySqlImpl ();
    
        @Override
        public void getUser () {
            userDao.getUser ();
        }
    }
    
    

    返回结果:

    image-20210731235441110

    接着如果再增加一个Oracle实现类,需要重复以上操作,需要增加UserDaoOracleImpl实现类、并修改UserServiceImpl对Dao层实现类对象创建

    将UserServiceImpl业务层实现类的new对象的操作,修改为private UserServiceOracleImpl userDao = new UserServiceOracleImpl ();

package com.wshy.Service;
import com.wshy.Dao.UserDao;
import com.wshy.Dao.UserDaoImpl;
import com.wshy.Dao.UserServiceMySqlImpl;
import com.wshy.Dao.UserServiceOracleImpl;

/**
 *
 * @title: UserServiceImpl
 * @Author: wshy
 */
public class UserServiceImpl implements UserService{

    //private UserDao userDao = new UserDaoImpl ();
    //private UserServiceMySqlImpl userDao = new UserServiceMySqlImpl ();
    private UserServiceOracleImpl userDao = new UserServiceOracleImpl ();

    @Override
    public void getUser () {
        userDao.getUser ();
    }
}

返回结果:

image-20210731235813259

那么问题来了,如果业务需要实现的类越来越多,那么每次都要手工去修改业务层UserService中对Dao层UserDaoXXXService实现类对象的创建

这样的操作,每当有请求修改,都要去修改代码,这种设计是不合理的!!!!

可以在业务层UserServiceImpl中对象的创建使用set注入,然后在测试类中,传入需要注入的对象即可,这样就不需要每次都去修改业务层的代码,不用在业务层每次都去new一个Dao层对象。

如下是对UserServiceImpl、MyTest中的修改及结果

package com.wshy.Service;
import com.wshy.Dao.UserDao;
import com.wshy.Dao.UserDaoImpl;
import com.wshy.Dao.UserServiceMySqlImpl;
import com.wshy.Dao.UserServiceOracleImpl;

import java.util.Set;

/**
 *
 * @title: UserServiceImpl
 * @Author: wshy
 */
public class UserServiceImpl implements UserService{

    //private UserDao userDao = new UserDaoImpl ();
    //private UserServiceMySqlImpl userDao = new UserServiceMySqlImpl ();
    //private UserServiceOracleImpl userDao = new UserServiceOracleImpl ();

    private UserDao userDao;

    // 利用set进行动态实现值得注入
    public void setUserDao (UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void getUser () {
        userDao.getUser ();
    }
}

import com.wshy.Dao.UserDaoImpl;
import com.wshy.Dao.UserServiceMySqlImpl;
import com.wshy.Service.UserService;
import com.wshy.Service.UserServiceImpl;

/**
 *
 * @title: MyTest
 * @Author: wshy
 */
public class MyTest {
    public static void main (String[] args) {

        // 用户实际调用的是业务层,Dao层并不接触
        UserServiceImpl userService = new UserServiceImpl ();
        userService.setUserDao(new UserServiceMySqlImpl ());

        userService.getUser ();
    }
}

image-20210801001737550

以上程序发生了本质的变化

  • 之前,程序是主动创建对象,控制权在程序员手中
  • 现在,使用set注入后,程序不再具有主动性,而是变成了被动的接收对象

这种思想,本质上解决了问题,我们程序员不用再去管理对象的创建了,系统耦合性大大降低!!!可以更加专注的在业务实现上,这是IOC的原型!

image-20210801002852661

3.IOC本质

控制反转(IOC),是一种设计思想,DI(依赖注入)是实现IOC的一种方法

在没有IOC的程序中,我们使用面向对象编程,对象的创建于对象之间的依赖关系完成硬编码的方式在程序中体现,对象的创建有程序自己控制,控制反转后将对象的创建转移到第三方,其本质就是**获得依赖对象的方式反转了**

从下面的图可以帮助理解

  • 图一,各个对象之间是强耦合的,程序决定依赖关系
  • 图二,各个对象中间加了一个中间容器,IOC容器,负责将各个对象之间关系进行解耦
  • 图三,各个对象之间的调用,没有任何耦合性

image-20210801003712748

IOC是Spring框架的核心内容,使用多种方式完美的实现了IOC,可以使用IOC的方式,可以使用注解的方式,也可以使用Spring新特性中的零配置(自动注入)实现IOC

spring在初始化时,先读取配置文件,根据配置文件信息或元数据创建组织对象存入容器中,程序使用时,再从IOC容器中获取所需对象。

image-20210801211304097

4.HelloSpring

4.1 hello.java

package com.wshy.pojo;

/**
 * @title: Hello
 * @Author: wshy
 */
public class Hello {
    private String str;

    public String getStr () {
        return str;
    }

    public void setStr (String str) {
        this.str = str;
    }

    @Override
    public String toString () {
        return "Hello{" +
                "str='" + str + '\'' +
                '}';
    }
}

4.2 beans.xml

<?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">

<!--使用spring创建对象,在spring中这些都被成为Bean-->
    <bean id="hello" class="com.wshy.pojo.Hello">
        <property name="str" value="Spring"/>
    </bean>

</beans>

4.3 MyTest

import com.wshy.pojo.Hello;
import javafx.application.Application;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @title: MyTest
 * @Author: wshy
 */
public class MyTest {
    public static void main (String[] args) {
        // 获取spring的上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext ("beans.xml");

        //我们的对象都在spring中管理了,我们要使用,直接去里面取就好了,取id为hello的Bean
        Hello hello = (Hello) context.getBean ("hello");
        System.out.println (hello.toString ());

    }
}

4.4 结果

image-20210801211943348

4.5 解析说明

beans.xml解析

<?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">
    <!--使用spring创建对象,在spring中这些都被成为Bean-->
    <!--
    以前创建对象
    类型   变量名  =  new 类型();
    Hello hello = new Hello();

    使用Beans.xml配置文件后
    id = 变量名
    class = new 对象
    property 相当于给对象中的属性设置一个值

    -->
    <bean id="hello" class="com.wshy.pojo.Hello">
        <property name="str" value="Spring"/>
    </bean>
</beans>

4.6 以spring的方式修改以前创建对象的方式

添加beans.xml

<?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="mysqlImpl" class="com.wshy.Dao.UserServiceMySqlImpl" />
    <bean id="oracleImpl" class="com.wshy.Dao.UserServiceOracleImpl" />
    
    <!--
		ref:引用spring容器中创建好的对象
		value:具体的值,基本数据类型
	-->
    <bean id="userServiceImpl" class="com.wshy.Service.UserServiceImpl">
        <property name="userDao" ref="mysqlImpl"/>
    </bean>

</beans>

修改MyTest.java

/**
 * @author wshy
 * @data 2021/7/31
 **/

import com.wshy.Dao.UserDaoImpl;
import com.wshy.Dao.UserServiceMySqlImpl;
import com.wshy.Service.UserService;
import com.wshy.Service.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 *
 * @title: MyTest
 * @Author: wshy
 */
public class MyTest {
    public static void main (String[] args) {

        // 用户实际调用的是业务层,Dao层并不接触
        //UserServiceImpl userService = new UserServiceImpl ();
        //userService.setUserDao(new UserServiceMySqlImpl ());
        //
        //userService.getUser ();

        ApplicationContext context = new ClassPathXmlApplicationContext ("beans.xml");
        UserServiceImpl userServiceImpl = (UserServiceImpl) context.getBean ("userServiceImpl");
        userServiceImpl.getUser ();
    }
}

运行结果

image-20210801215542694

此时,如果想要修改业务,只需要修改配置文件中的ref引用为oracleImpl,接口打印出**Oracle实现类

总结

  1. hello对象是由spring创建的
  2. hello对象的属性是在spring配置文件中设置的

这个过程就是控制反转:

  • 控制:谁来控制对象的创建,传统应用程序的对象是由程序本身创建的,使用spring后,对象由spring来创建
  • 反转:程序本身不创建对象,而变成被动的接收对象
  • 依赖注入:就是利用set方法来实现注入的

IOC是一种编程思想,由主动创建对象 ,变为被动接收

我们可以彻底不用修改代码,而去实现不同的操作,只需要在xml配置文件中红进行修改,所谓的IOC,就是由spring来创建、管理、装配对象!

相关文章:

  • Spring创建对象的几种方式
  • Java服务后台启动问题总结
  • springboot自定义starter并上传至公网调用
  • 正向代理、反向代理、负载均衡
  • 64位linux编译32位程序
  • Python tips: 什么是*args和**kwargs?
  • 关于SAP UI5数据绑定我的一些原创内容
  • 安卓微信视频最佳实践
  • 触摸事件分发核心机制优化吸收
  • 异常机制详解
  • oracle 10g 搭建备库以及一次DG GAP的处理情况
  • 智能分析---表格的智能洞察
  • 线性代数学习
  • [VSCode] Shortcuts
  • Cannot retrieve metalink for repository: epel 错误解决
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • .pyc 想到的一些问题
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • 03Go 类型总结
  • Fastjson的基本使用方法大全
  • java8-模拟hadoop
  • mongodb--安装和初步使用教程
  • Python十分钟制作属于你自己的个性logo
  • ⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)
  • windows下如何用phpstorm同步测试服务器
  • 爱情 北京女病人
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 如何进阶一名有竞争力的程序员?
  • 深入浅出webpack学习(1)--核心概念
  • 手机app有了短信验证码还有没必要有图片验证码?
  • 王永庆:技术创新改变教育未来
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • 1.Ext JS 建立web开发工程
  • python最赚钱的4个方向,你最心动的是哪个?
  • 阿里云API、SDK和CLI应用实践方案
  • 说说我为什么看好Spring Cloud Alibaba
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (3)选择元素——(14)接触DOM元素(Accessing DOM elements)
  • (Matalb回归预测)PSO-BP粒子群算法优化BP神经网络的多维回归预测
  • (强烈推荐)移动端音视频从零到上手(下)
  • (转)linux下的时间函数使用
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .net流程开发平台的一些难点(1)
  • .NET牛人应该知道些什么(2):中级.NET开发人员
  • @KafkaListener注解详解(一)| 常用参数详解
  • @private @protected @public
  • @取消转义
  • [.NET]桃源网络硬盘 v7.4
  • []Telit UC864E 拨号上网
  • [《百万宝贝》观后]To be or not to be?
  • [100天算法】-实现 strStr()(day 52)
  • [BZOJ 3531][Sdoi2014]旅行(树链剖分+线段树)
  • [C++ 从入门到精通] 12.重载运算符、赋值运算符重载、析构函数
  • [C++]打开新世界的大门之C++入门