spring 认证--2--Spring DI--依赖注入/IOC-DI解耦

本文介绍了Spring的依赖注入(DI)原理,通过@Bean和@Autowired注解展示了如何在配置类中实现组件的初始化和注入。同时,通过实例详细解释了如何利用接口实现IOC/DI解耦,以及@Autowired注解的注入规则,强调了类型注入和组件扫描在简化代码和提高效率方面的作用。
摘要由CSDN通过智能技术生成

一 依赖注入

1 什么是依赖注入

 

2 @Bean注入

  Spring IOC容器提供了依赖注入功能,可以将一个组件依赖的对象,在使用之前注入到合适位置.比如,如下关系模拟了光头强砍树时依赖电锯.

  Spring IOC 解决依赖注入,在配置类Config中为Bean组件初始化方法增加参数,Spring IOC 容器会在初始化时,自动根据类型注入Bean组件对象,解决"依赖注入"问题:

2.1 测试@Bean组件注入的作用:

第一步:新创建spring2工程,pom文件添加依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.2.RELEASE</version>
        </dependency>
        <!--JUnit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
        <!---->
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
            <version>1.3.2</version>
        </dependency>
    </dependencies>

第二步: 分别在demo包下创建工具类和工人类,

package cn.tedu.demo;

import java.io.Serializable;

public class Saw implements Serializable {
    private String name = "寒冰锯";

    @Override
    public String toString() {
        return name;
    }
}
package cn.tedu.demo;

import java.io.Serializable;

public class Worker implements Serializable {
    private String name = "光头强";

    public Saw saw;

    public void work(){
        System.out.println(name+"使用"+saw+"砍树");
    }
}

第三步:编辑配置类,使用@Bean依赖注入,是两者产生联系

package cn.tedu.context;

import cn.tedu.demo.Saw;
import cn.tedu.demo.Worker;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Config {

    @Bean
    public Saw saw(){
        return new Saw();
    }
    /*Spring 会自动根据变量类型匹配Bean组件的类型
    * 若匹配成功,就将Bean组件注入到方法参数中*/
    @Bean
    public Worker worker(Saw s){//参数类型要匹配正确
        Worker worker = new Worker();
        worker.saw=s;
        return worker;
    }
}

第四步:test包下创建测试类,控制台查看结果

package cn.tedu.test;

import cn.tedu.context.Config;
import cn.tedu.demo.Worker;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestCase {
    AnnotationConfigApplicationContext ctx;
    @Before//初始化
    public void init(){
        ctx =new AnnotationConfigApplicationContext(Config.class);
    }

    @After//销毁方法
    public void destroy(){
        ctx.close();
    }

    @Test
    public void testWorker(){
        Worker worker = ctx.getBean("worker", Worker.class);
        worker.work();//光头强使用寒冰锯砍树
    }
}

2.2 Spring IOC组件注入时组件自动匹配通过类型和Bean Id匹配

 

 

3 @Autowired 自动装配(布线)

Spring 提供的组件扫描功能,在扫描时也可以完成依赖注入,这样可以减少编码提高编程效率

如何使用@Autowired?注入到对象属性上和注入到set方法上,看情况使用!!!

以下练习注入到对象属性上:

 第一步:创建新工程spring03,复制spring2的src包,分别编辑工具类和工人类,配置类添加包扫描组件

 

 第二步:测试类不变,进行测试,结果还是一样,所以,添加组件扫描和依赖注入,能够减少代码并提高编程效率

4   set方法注入(Bean属性注入)

 

 

@Autowired注入到set方法上:具有一定的逻辑

第一步:其他都不变,编辑worker类

 第二步:进行测试set方法注入的效果:

二  IOC/DI 解耦

1 利用IOC/DI依赖注入接口解耦

 

 第一步:创建新项目spring4,编辑pom.xml文件添加版本依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.2.RELEASE</version>
        </dependency>
        <!--JUnit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
        <!---->
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
            <version>1.3.2</version>
        </dependency>
    </dependencies>

 第二步:cn.tedu.demo包下创建Tool工具接口

package cn.tedu.demo;
/*抽象的工具类型*/
public interface Tool {
}

第三步:创建工人类,电锯类和斧子类

package cn.tedu.demo;

import org.springframework.stereotype.Component;

@Component//组件扫描,交给spring创建对象
public class Axe implements Tool{
    private String name = "开天斧";

    @Override
    public String toString() {
        return name;
    }
}
package cn.tedu.demo;
//没有加组件扫描,就不会被spring创建对象
public class Saw implements Tool{
    private String name="寒冰锯";

    @Override
    public String toString() {
        return name;
    }
}
package cn.tedu.demo;

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

@Component
public class Worker implements Serializable{
    private String name= "光头强";

    @Autowired//接口的依赖注入
    private Tool tool;

    public void work(){
        System.out.println(tool);
        System.out.println(tool == null);
        System.out.println(name+"使用"+tool+"砍树");
    }
}

第四步:创建配置类,用于扫描包

package cn.tedu.context;

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

@Configuration
@ComponentScan("cn.tedu.demo")//配置类扫描包,spring为其包下的类创建对象
public class Config {
}

第五步:创建测试类:

package cn.tedu.test;

import cn.tedu.context.Config;
import cn.tedu.demo.Worker;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestCase {

    AnnotationConfigApplicationContext ctx;
    @Before//初始化
    public void init(){
        ctx = new AnnotationConfigApplicationContext(Config.class);
    }

    @After//销毁
    public void destroy(){
        ctx.close();
    }

    @Test //测试接口解耦
    public void testWorker(){
        Worker worker = ctx.getBean("worker", Worker.class);
        worker.work();

    }
}

控制台:

 第六步:如果想使用电锯类,就要把@Component添加到电锯类上,去掉斧子类的@Component组件扫描

 第七步:测试

 2 @Autowried 注入规则

 

当电锯类和斧子类都加了@Component组件扫描时:

方案1:  需要自定义组件ID

 第一步:如果使用斧子类,就自定义组件ID,使其能被识别

 测试结果:

 第二步:如果使用电锯类,自定义组件ID,注意,斧子类上的自定义组件ID就要删除

 测试结果:

 方案2:利用注解@Qualifier("Bean ID") 指定注入bean组件的id

假如想使用电锯,就要在依赖注入接口再添加@Qualifier("saw"),指定使用电锯对象

 同样,想使用斧子,就要在依赖注入接口再添加@Qualifier("axe"),指定使用斧子对象

总结

这两种方案能解决冲突,但实际开发当中用处并不多,而是尽量采用类型注入,默认值注入等更方便的方法,保证每个一个组件都有唯一的名字

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值