当前位置 博文首页 > Welcome to 七元K home page:??六万字《Spring框架从入门到精通

    Welcome to 七元K home page:??六万字《Spring框架从入门到精通

    作者:[db:作者] 时间:2021-09-12 12:04

    ?? Spring

    代码:https://github.com/Donkequan/Spring-Study

    ?? 希望各位博友三连+关注!!!

    1、简介

    spring理念:是现有的技术更加容易使用,本身是一个大杂烩。

    • SSH:Struct2 + Spring + Hibernate
    • SSM: SpringMVC + Spring + Mybatis

    官网: https://spring.io/projects/spring-framework#overview

    官方下载: https://repo.spring.io/release/org/springframework/spring/

    GitHub: https://github.com/spring-projects/spring-framework

    1.1、导入包

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.9</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.3.9</version>
    </dependency>
    
    
    

    1.2、优点

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

    总结:spring是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架。

    1.3、Spring组成

    img

    img

    1.4、拓展

    1. Spring Boot 构建一切
      1. 一个快速开发的脚手架
      2. 基于SpringBoot可以快速的开发单个微服务
      3. 约束大于配置!
    2. Spring Cloud 协调一切
      1. SpringCloud是基于SpringBoot实现的
    3. Spring Cloud Data Flow 连接一切

    学习SpringBoot的前提,需要完全掌握Spring以及SpringMVC!

    2、IOC理论推导

    1. UserDao
    2. UserDaoImp
    3. UserSevice
    4. UserServiceImp

    在之前,用户的需求可能会影响原来的代码。

    2.1、分析实现

    新建一个空白的maven项目

    分析实现

    我们先用我们原来的方式写一段代码 .

    1、先写一个UserDao接口

    public interface UserDao {
      public   void getUser();
    }
    
    

    2、再去写Dao的实现类

    public class UserDaoImp implements UserDao{
        @Override
        public void getUser() {
            System.out.println("默认获取用户的数据");
        }
    }
    
    

    3、然后去写UserService的接口

    public interface UserService {
        public void getUser();
    }
    

    4、最后写Service的实现类

    public class UserServiceImp implements UserService{
    
        private UserDao userDao = new UserDaoImp();
    
        public void getUser(){
            userDao.getUser();
        }
    }
    
    

    5、测试一下

    @Test
    public void MyTest(){
        UserService service = new UserServiceImpl();
        service.getUser();
    }
    

    这是我们原来的方式 , 开始大家也都是这么去写的对吧 . 那我们现在修改一下 .

    把Userdao的实现类增加一个 .

    public class UserDaoMysqlImp implements UserDao{
        @Override
        public void getUser() {
            System.out.println("Mysql获取用户数据!");
        }
    }
    

    紧接着我们要去使用MySql的话 , 我们就需要去service实现类里面修改对应的实现

    public class UserServiceImpl implements UserService {
       private UserDao userDao = new UserDaoMySqlImpl();
    
       @Override
       public void getUser() {
           userDao.getUser();
      }
    }
    

    在假设, 我们再增加一个Userdao的实现类 .

    public class UserDaoOracleImpl implements UserDao {
       @Override
       public void getUser() {
           System.out.println("Oracle获取用户数据");
      }
    }
    

    那么我们要使用Oracle , 又需要去service实现类里面修改对应的实现 . 假设我们的这种需求非常大 , 这种方式就根本不适用了, 甚至反人类对吧 , 每次变动 , 都需要修改大量代码 . 这种设计的耦合性太高了, 牵一发而动全身 .

    那我们如何去解决呢 ?

    我们可以在需要用到他的地方 , 不去实现它 , 而是留出一个接口 , 利用set , 我们去代码里修改下 .

    public class UserServiceImpl implements UserService {
       private UserDao userDao;
    // 利用set实现
       public void setUserDao(UserDao userDao) {
           this.userDao = userDao;
      }
    
       @Override
       public void getUser() {
           userDao.getUser();
      }
    }
    

    现在去我们的测试类里 , 进行测试 ;

    public class MyTest {
        public static void main(String[] args) {
            //用户实际调用的是业务层,dao层他们不需要接触!
            UserServiceImp userService = new UserServiceImp();
            ((UserServiceImp) userService).setUserDao(new UserDaoSqlserviceImp());
            userService.getUser();
        }
    }
    

    使用一个set。

       private UserDao userDao;
          //利用set进行动态实现值的注入
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
    • 之前是主动创建对象,控制权在程序猿手上!
    • 使用set之后,程序不再具有主动性,而是变成了被动接受对象。

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

    2.2、IOC本质

    控制反转IoC(Inversion of Control),是一种设计思想,**DI(依赖注入)是实现IoC的一种方法,**也有人认为DI只是IoC的另一种说法。没有IoC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。

    img

    IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC。

    Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。

    img

    采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

    控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。

    示例:

    HelloSpring

    1、导入Jar包

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.9</version>
    </dependency>
    

    2、编写一个Hello实体类

    public class Hello {
       private String name;
    
       public String getName() {
           return name;
      }
       public void setName(String name) {
           this.name = name;
      }
    
       public void show(){
           System.out.println("Hello,"+ name );
      }
    }
    

    3、编写我们的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">
    
    <!--    使用Spring来创建对象,在Spring中这些都称为Bean
            类型 变量名  = new 类型
            Hello hello = new Hello();
            bean=对象 new Hello()
    
            id=变量名
            class=new 的对象
            property 相当于给对象中的属性设置有一个值
    -->
        <bean id="hello" class="com.kk.pojo.Hello">
            <property name="str" value="Spring">
            </property>
        </bean>
    
    
    </beans>
    

    4、测试

    import com.kk.pojo.Hello;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MyTest {
        public static void main(String[] args) {
            //获取Spring的上下文对象
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            //我们的对象现在都在Spring中管理了,我们要使用,直接去里面取出来就可以了
            Hello hello = (Hello)context.getBean("hello");
            hello.show();
    //        System.out.println(hello.toString());
    
    
        }
    }
    

    思考

    • Hello 对象是谁创建的 ? 【hello 对象是由Spring创建的
    • Hello 对象的属性是怎么设置的 ? hello 对象的属性是由Spring容器设置的

    这个过程就叫控制反转 :

    • 控制 : 谁来控制对象的创建 , 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , 对象是由Spring来创建的
    • 反转 : 程序本身不创建对象 , 而变成被动的接收对象 .

    依赖注入 : 就是利用set方法来进行注入的.

    IOC是一种编程思想,由主动的编程变成被动的接收

    可以通过newClassPathXmlApplicationContext去浏览一下底层源码 .

    修改案例一

    我们在案例一中, 新增一个Spring配置文件beans.xml

    注入:
    1.ref:引用Spring容器中创建好的对象
    2.value:具体的值,基本数据类型

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"