Spring 札记(一、IOC思想与DI实现)In the spring of learning

一:Spring简介

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

优点:

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

二:IOC理念

之前,程序是主动创建对象,也就是说控制权在程序员手中

如今,使用set注入后,程序不再具有主动性,而是变成了被动的接受对象

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

案例分析:

1、新建一个模块

2、导入依赖坐标

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

导入这个 spring-webmvc 会自动导入其他相应的依赖
在这里插入图片描述

3、建立包结构 dao层 impl层 service层

在这里插入图片描述

Dao层

用户功能接口 UserDao

// 用户功能接口
public interface UserDao {

    //店铺服务
    void CallWaiter();
}

用户接口的一个实现类 功能是

import com.csnz.dao.UserDao;
// 用户接口的一个实现类  功能是 喝
public class DrinkDaoImpl implements UserDao {
    @Override
    public void CallWaiter() {
        System.out.println("服务生来瓶 95年的 Java");
    }
}

用户接口的一个实现类 功能是 洗脚

import com.csnz.dao.UserDao;

    // 用户接口的一个实现类  功能是 洗脚
public class WashFeetDaoImpl implements UserDao {
    @Override
    public void CallWaiter() {
        System.out.println("服务生 过来帮我洗jio~");
    }
}

用户接口的一个实现类 功能是 按摩

import com.csnz.dao.UserDao;
// 用户接口的一个实现类  功能是 按摩
public class MassageDaoImpl implements UserDao {
    @Override
    public void CallWaiter() {
        System.out.println("服务生 过来帮我按摩");
    }
}
Service层

用户功能 服务接口(业务层)

// 用户功能 服务接口(业务层)
public interface UserService {
    //店铺服务
    void CallWaiter();
}

业务层 接口 实现类

import com.csnz.dao.UserDao;
import com.csnz.dao.impl.DrinkDaoImpl;
import com.csnz.service.UserService;
// 业务层 接口 实现类
public class UserServiceImpl implements UserService {
    // 用户调用业务层 -> 调用dao层 ->调用dao层的方法
    private UserDao userDao = new DrinkDaoImpl();
    @Override
    public void CallWaiter() {
        userDao.CallWaiter();
    }
}

4、测试

import com.csnz.service.UserService;
import com.csnz.service.impl.UserServiceImpl;

public class UserTest {
    public static void main(String[] args) {
        UserService  userService = new UserServiceImpl();
        //用户通过调用业务层 去执行 需求
        userService.CallWaiter();
    }
}

结果可想而知
在这里插入图片描述

那么此时我们想洗脚的话 咋办呢?

那么就得去修改业务层实现类的方法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

所以说要 洗脚 修改业务 不是很麻烦吗?每次都得修改源码

改用set注入方式
在这里插入图片描述
现在想 干啥就干啥 轻轻松松 洗脚都不怕被发现了
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
只需修改参数即可 ~ 这就是是IOC的基本思想 控制反转

三:IOC练习

建项目 重复的步骤就不说了。看上面就知道。
在这里插入图片描述
实体类:

// 实体类 要让Spring完成注入 必须实现 空构造器 和 set方法
public class Hello {
    private String name;

    public Hello() {
    }

    public Hello(String name) {
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }

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

Spring的核心配置文件 application-context.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
    id = 变量名称 class为你要new的对象的路径
    property 相当于 给对象中的属性设置一个值
    注意:
    如果实体类中没有无参构造器 class 引用会报错
    如果实体类中没有set方法   property就无法 实现注入
-->
<bean id="hello" class="com.csnz.pojo.Hello">
    <property name="name" value="潮汕奴仔"/>
</bean>
</beans>

测试类

import com.csnz.pojo.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
    public static void main(String[] args) {
        // 获取Spring 的上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
        // 我们的对象现在都在Spring 中 统一管理了,如果要使用的话 根据Bean的name直接取出来
        Hello h =(Hello) context.getBean("hello");
        System.out.println(h.toString());
    }
}

执行结果
在这里插入图片描述

至此,我们彻底不用 再去 程序中修改了,要实现不同的操作,只需修改XML配置文件

yyds的IOC思想:对象由Spring来创建,管理,装配!

既然如此,那么我们就可以将 洗 jio的 demo也修改一下

application-context.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
    id = 变量名称 class为你要new的对象的路径
    property 相当于 给对象中的属性设置一个值
    注意:
    如果实体类中没有无参构造器 class 引用会报错
    如果实体类中没有set方法   property就无法 实现注入
-->
<bean id="washFeet" class="com.csnz.dao.impl.WashFeetDaoImpl"/>
<bean id="drink" class="com.csnz.dao.impl.DrinkDaoImpl"/>
<bean id="massage" class="com.csnz.dao.impl.MassageDaoImpl"/>
<bean id="userService" class="com.csnz.service.impl.UserServiceImpl">
    <property name="userDaoImpl" ref="washFeet"/>
</bean>
</beans>

UserServiceImpl

import com.csnz.dao.UserDao;
import com.csnz.dao.impl.DrinkDaoImpl;
import com.csnz.dao.impl.WashFeetDaoImpl;
import com.csnz.service.UserService;
// 业务层 接口 实现类
public class UserServiceImpl implements UserService {
    // 用户调用业务层 -> 调用dao层 ->调用dao层的方法
//    private UserDao userDao = new WashFeetDaoImpl();

    private UserDao userDaoImpl;
    
    //set方法实现注入
    public void setUserDaoImpl(UserDao userDaoImpl) {
        this.userDaoImpl = userDaoImpl;
    }
    public  UserServiceImpl(UserDao userDaoImpl){
        this.userDaoImpl = userDaoImpl;
    }

    //无参构造器
    public UserServiceImpl() {}

    @Override
    public void CallWaiter() {
        userDaoImpl.CallWaiter();
    }
    
}

测试 UserTest

import com.csnz.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserTest {
    public static void main(String[] args) {
        /*
        UserService  userService = new UserServiceImpl(new MassageDaoImpl());
        //用户通过调用业务层 去执行 需求
        userService.CallWaiter();
        */
        // 获取Spring 的上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
        // 我们的对象现在都在Spring 中 统一管理了,如果要使用的话 根据Bean的name直接取出来
        UserService userService = (UserService) context.getBean("userService");
        userService.CallWaiter();
    }
}

洗jio 成功
在这里插入图片描述

四:IOC创建对象的方式(4种)

1、使用无参构造创建对象,默认。(1种)

ApplicationContext context = new ClassPathXmlApplicationContext(“application-context.xml”);
读取配置文件时 就会创建bean对象

2、假设我们要使用有参构造创建对象(3种)

有三种形式

  1. 通过参数名 设置值创建
    <constructor-arg name="name" value="通过参数名 设置值"/>

  2. 通过类型匹配创建
    <constructor-arg type="java.lang.String" value="通过类型匹配创建 不建议使用"/>

  3. 下标赋值创建
    <constructor-arg index="0" value="测试有参构造器通过下标赋值创建对象"/>

总结:在配置文件加载的时候,容器中管理的对象就已经初始化了

五:IOC本质

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

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

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

六:IOC实现:

1:首先定义用来描述bean的配置的Java类

2:解析bean的配置(Bean.xml),將bean的配置信息转换为上面的BeanDefinition对象保存在内存中,spring中采用HashMap进行对象存储,其中会用到一些xml解析技术

3:遍历存放BeanDefinition的HashMap对象,逐条取出BeanDefinition对象,获取bean的配置信息,利用Java的反射机制实例化对象,将实例化后的对象保存在另外一个Map中即可(key:beanName value:beanDefinition)

七:依赖注入 如何实现?

Java 1.3之后一个重要特征是反射(reflection)

允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的

八:DI实现方法

依赖注入可以通过setter方法注入(设值注入)构造器注入接口注入(在spring中没有,但是Java中还是有的) 三种方式来实现,Spring支持setter注入和构造器注入,通常使用构造器注入来注入必须的依赖关系,对于可选的依赖关系,则setter注入是更好的选择,setter注入需要类提供无参构造器或者无参的静态工厂方法来创建对象。

评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值