Spring的依赖注入DI

Spring的依赖注入

1.1依赖注入案例

1.1.1定义Pet类

package com.jt.demo4;
public interface Pet {
    void hello();
}

1.1.2定义Dog类

注解:@Component==>将该类交给Spring容器管理 key:小写类名 value:反射机制创建对象

  • 默认值时小写的类名,可以另外单独命名(@Component("/abc"))
package com.jt.demo4;
@Component//将该类交给Spring容器进行管理  key:dog(类名首字母小写) value:反射机制创建对象
public class Dog implements Pet {

    @Override
    public void hello() {
        System.out.println("快到圣诞节了!!!");
    }
    public Dog() {
        System.out.println("dog的无参构造!!!");
    }
}

1.1.3定义User类

注解:@Component==>将User对象交给容器管理

@Autowired==>可以将容器中的对象进行注入(默认类型注入)

  • 按照类型注入: 如果注入的类型是接口;则自动查找其实现类对象进行注入
    • 注意事项: 一般Spring框架内部的接口都是单实现;特殊情况下可以多实现
  • 按照名称注入:@Autowired + @Qualifier(“dog”)==>按照id(类的小写名称即Map中的key值)进行注入
package com.jt.demo4;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component //将User对象交给容器管理
public class User {
    /**
     * 注入:将spring容器中的对象进行引用
     * @Autowired: 可以将容器中的对象进行注入
     * 1.按照类型注入: 如果注入的类型是接口;则自动查找其实现类对象进行注入
     * 注意事项: 一般Spring框架内部的接口都是单实现;特殊情况下可以多实现
     * 2.按照名称注入:
     */
    @Autowired
    private Pet pet;
    public void hello() {
        pet.hello();
    }
    public User() {
        System.out.println("我是User的无参");
    }
}

1.1.4 编辑配置类

注解:@Configuration:标识该类为配置类
**@ComponentScan(“com.jt.demo4”)**扫描本包及子孙包的注解

package com.jt.demo4;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.jt.demo4")
public class SpringConfig {
    
}

1.1.5 编辑测试代码

package com.jt.demo4;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringDI {
    public static void main(String[] args) {
        ApplicationContext context =
                new AnnotationConfigApplicationContext(SpringConfig.class);
        User user = context.getBean(User.class);
        user.hello();
    }
}

1.1.6运行流程(类型注入)

image-20211223110403192

1.2 多实现类案例讲解

1.2.1 关于案例说明

一般条件下Spring接口都是单实实现,如果遇到多实现,则需要利用按名称注入方式(@Autowired + @Qualifier(“dog”))

在这里插入图片描述

程序报错

  • 解决方法:利用名称注入@Autowired+@Qualifier(“dog”)

    在这里插入图片描述

1.3MVC设计思想

1.3.1传统代码结构

说明:如果将所有业务代码都写到一个方法中,则导致后期维护耦合性高,为了提高程序的扩展性,将程序按照MVC设计思想 进行管理

1.3.2MVC设计思想说明

M:Model 数据层

V:View 视图层

C:Control 控制层

总结:MVC主要的目的降低代码的耦合性,提高扩展性,方便后续开发

image-20211223112405356

1.3.3三层代码结构

说明: 基于MVC设计思想的启发,在后端为了提高代码的扩展性,一般将后端代码分为三层.
分层:

  1. Controller层 主要与页面进行交互 @Controller
  2. Service层 主要实现后端的业务逻辑 @Service
  3. Dao层/Mapper层 主要与数据库进行交互 也把该层称之为 “持久层” @Respository/Mapper

1.4"三层"代码结构实现

1.4.1代码结构说明

  • 包名:mapper 类两个 一个接口UesrMapper/一个类UserMapperImpl

  • 包名:service 类两个 一个接口UesrService/一个类UserServiceImpl

  • 包名:controller 一个类:UserController

知识说明:存在业务关系时,被调用的一般会有接口和实现类

1.5@Value注解说明

1.5.1 编辑properties文件

#1.数据结构; key=value
#2.无需添加多余的引号
#3.注意多余的空格
#4.程序在读取properties文件时,默认采用ISO-8859-1编码!!!中文必乱码
name=张三

1.5.2 编辑UserMapper

public interface UserMapper {

	void addUser();
}

1.5.3 编辑UserMapperImpl

注解
  • @PropertySource(value=“classpath:/addUser.properties”,encoding = “UTF-8”)
    • Spring根据指定的路径,加载properties配置文件 数据以键值对Map<key,value>添加到了Spring容器中
    • 见注解@PropertySource就
      • 写classpath:配置的路径
      • 写encoding=“utf-8”:配置字符集
package com.jt.demo6.mapper;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Repository;

@Repository
//spring根据指定的路径,加载properties配置文件 数据添加到spring容器中
@PropertySource(value="classpath:/addUser.properties",encoding = "UTF-8")
public class UserMapperImpl implements UserMapper{
    /**
     * @Value 注解的作用: 为属性赋值
     *        需求:  从spring容器中动态获取数据
     */
    @Value("${name}")
    //@Value("张三")  //直接写法,扩展性不好
    private String name;

    @Override
    public void addUser() {
        System.out.println("新增用户:" + name);
    }
}

1.5.4 编辑测试类

package com.jt.demo6;

import com.jt.demo6.config.SpringConfig;
import com.jt.demo6.mapper.UserMapper;
import com.jt.demo6.mapper.UserMapperImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringValue {

    public static void main(String[] args) {
        ApplicationContext context =
                new AnnotationConfigApplicationContext(SpringConfig.class);
        //获取的对象 实现类和接口都可以.
        UserMapper userMapper = context.getBean(UserMapper.class);
        userMapper.addUser();
    }
}

mvc架构运行机制

Spring容器开始启动===>调用配置类SpringConfig–>@CompontScan("")扫描

扫描1—>扫描Controller–>通过@Autowired注入Service(由于现在还没扫描到Service所以先忽略@Controller注解下去找Service)=>挂起

扫描2—>扫描mapper–>找到@Repository将mapper实现类MapperImpl交给容器管理

扫描3—>扫描service–>找到注解@Autowired(此时spring容器中只有一个对象(Mapper实现类,controller还没有完成,所以controller不在容器中)将UserMapper注入(面向接口开发,所以不传实现类)—>扫描到@Service将Service交给容器管理(此时容器两个对象)------>回到扫描 1 的挂起

扫描1.1=>挂起—>将Service注入到Controller—>扫描@controller将Controller交给容器

=>>>>>>>Spring容器启动成功(此时三个对象在容器中)

==>context.getBean(UserController.class);拿到controller

==>调用

调用图解

在这里插入图片描述

1.6关于IOC-DI的总结

  • 什么是IOC:控制反转,将对象交给Spring容器管理,由容器管理对象生命周期

  • 什么是DI:依赖注入,为当前对象注入属性

  • 总结: 使用IOC-DI可以极大程度上实现代码的松耦合(解耦)

常用注解

  1. @ComponentScan 包扫描注解 扫描注解
  2. @Bean 标识该方法的返回值交给Spring容器管理
  3. @Scope 控制多例和单例
    1. ​ @Scope(“prototype”)//表示多例对象
    2. ​ @Scope(“singleton”)//表示单例对象
  4. @Lazy 懒加载
  5. @PostConstruct 初始化方法
  6. @PreDestroy 销毁方法
  7. @Component 将当前类未来的对象交给容器管理
  8. @Autowired 按照类型进行注入
  9. @Qualifier 按照名称进行注入
  10. @Repository 标识持久层注解
  11. @Service 标识Service层
  12. @Controller 标识Controller层
  13. @Value 为属性赋值
  14. @PropertySource 加载指定路径的配置文件properties
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值