一 依赖注入

1.1 什么是依赖注入

1.2 @Bean注入

spring IOC容器提供了依赖注入功能,可以将一个组件依赖到的对象,在使用之前注入到合适位置

spring IOC解决依赖注入;在配置类congfig中为Bean组件初始化方法增加参数,spring IOC容器会在初始化时候自动根据类型注入Bean组件对象

案例:

1.创建Saw

package cn.tedu.demo;import java.io.Serializable;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
public class Saw implements Serializable {private String name="开天斧";@Overridepublic String toString() {return name;}
}

2.创建Worker

package cn.tedu.demo;import java.io.Serializable;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
public class Worker implements Serializable {private String name="光头强";public Saw saw;public void work(){System.out.println(name + "使用" + saw +"砍树");}}

3.创建配置文件

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;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
@Configuration
public class Config {@Beanpublic Saw saw(){return new Saw();}@Bean/*** spring会自动根据变量类型匹配Bean组件的类型* 如果匹配上,就将Bean组件注入到方法参数中*/public Worker worker(Saw s){Worker worker = new Worker();worker.saw=s;return worker;}
}

4.测试案例

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;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
public class TestCase {AnnotationConfigApplicationContext ctx;@Beforepublic void init(){ctx=new AnnotationConfigApplicationContext(Config.class);}@Afterpublic void destroy(){ctx.close();}@Testpublic void testWorker(){Worker worker = ctx.getBean("worker", Worker.class);worker.work();}
}

运行结果:

光头强使用开天斧砍树

 spring IOC组件注入时候组件自动匹配规则:

  1. 首先按照注入参数类型查找相应类型的Bean组件,如果没有直接报错误
  2. 如果在是spring容器中能够匹配上唯一类型的Bean组件,则进行注入成功
  3. 如果按照类型匹配到两个bean组件,则查找组件ID和变量名是否匹配,如果匹配则注入成功
  4. 如果组件类型和组件ID都不能很好匹配则报错

注入失败案例

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;
import org.springframework.context.annotation.Scope;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
@Configuration
public class Config {@Beanpublic Saw saw(){return new Saw();}@Beanpublic Saw saw2(){return new Saw();}@Bean/*** spring会自动根据变量类型匹配Bean组件的类型* 如果匹配上,就将Bean组件注入到方法参数中*/public Worker worker(Saw s){Worker worker = new Worker();worker.saw=s;return worker;}
}

运行结果:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'worker' defined in cn.tedu.context.Config: Unsatisfied dependency expressed through method 'worker' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'cn.tedu.demo.Saw' available: expected single matching bean but found 2: saw,saw2

碰到这种问题,只需要将需要注入的类型名改为@Bean相同的类型名

1.3 @Autowired

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

案例

创建电锯类Saw

package cn.tedu.demo;import org.springframework.stereotype.Component;import java.io.Serializable;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
@Component
public class Saw implements Serializable {private String name="开天斧";@Overridepublic String toString() {return name;}
}

创建工人类Worker

package cn.tedu.demo;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.io.Serializable;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
@Component
public class Worker implements Serializable {private String name="光头强";@Autowiredpublic Saw saw;public void work(){System.out.println(name + "使用" + saw +"砍树");}}

创建配置类

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.ComponentScan;
import org.springframework.context.annotation.Configuration;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
@Configuration
@ComponentScan(basePackages = "cn.tedu.demo")
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;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
public class TestCase {AnnotationConfigApplicationContext ctx;@Beforepublic void init(){ctx=new AnnotationConfigApplicationContext(Config.class);}@Afterpublic void destroy(){ctx.close();}@Testpublic void testWorker(){Worker worker = ctx.getBean("worker", Worker.class);worker.work();}
}

测试结果

光头强使用开天斧砍树

1.4 set方法注入

测试案例:

二 IOC/DI解耦

2.1 利用接口解耦

利用spring IOC容器提供的DI可以将工具对象注入给工人对象,继而解决之间的依赖关系,并且由于依赖于接口,所以利用spring IOC就可以控制组件的组合关系,实现松耦合

案例:利用spring实现解耦

声明工具接口

package cn.tedu.demo2;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
/*** 抽象的工具类型* */
public interface Tool {
}

声明工人类

package cn.tedu.demo2;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.io.Serializable;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
@Component
public class Worker implements Serializable {private String name="光头强";@Autowiredprivate Tool tool;public void work(){System.out.println(name + "使用" + tool +"砍树");}
}

声明电锯类

package cn.tedu.demo2;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
public class Saw implements Tool{private String name="小锯子";@Overridepublic String toString() {return name;}
}

声明斧子类

package cn.tedu.demo2;import org.springframework.stereotype.Component;import java.io.Serializable;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
@Component
public class Axe implements Serializable,Tool{private String name="开天斧";@Overridepublic String toString() {return name;}
}

配置类

package cn.tedu.context2;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
@Configuration
@ComponentScan(basePackages = "cn.tedu.demo2")
public class Config {
}

测试类

package cn.tedu.test;import cn.tedu.context2.Config;
import cn.tedu.demo2.Worker;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
public class TestCase2 {AnnotationConfigApplicationContext ctx;@Beforepublic void init(){ctx=new AnnotationConfigApplicationContext(Config.class);}@Afterpublic void destroy(){ctx.close();}@Testpublic void testWorker(){Worker worker = ctx.getBean("worker", Worker.class);worker.work();}
}

测试结果

光头强使用开天斧砍树

2.2 @Autowired注入规则

案例:将斧子类和电锯类都加上@Component注解

1.在斧子类上设置自定义BeanID

package cn.tedu.demo2;import org.springframework.stereotype.Component;import java.io.Serializable;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
@Component("tool")
public class Axe implements Serializable,Tool{private String name="开天斧";@Overridepublic String toString() {return name;}
}

测试结果:

光头强使用开天斧砍树

2.重构Worker类,设定@Qualifier("saw")

package cn.tedu.demo2;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;import java.io.Serializable;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
@Component
public class Worker implements Serializable {private String name="光头强";@Autowired@Qualifier("saw")private Tool tool;public void work(){System.out.println(name + "使用" + tool +"砍树");}
}

测试结果:

光头强使用小锯子砍树

2.3 同时使用@Bean @Component

1.利用@Bean在配置类Config中声明组件

package cn.tedu.context2;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;import java.util.Date;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
@Configuration
@ComponentScan(basePackages = "cn.tedu.demo2")
public class Config {@Beanpublic Date date(){return new Date();}
}

2.利用@Component声明组件,注入Date类型组件

package cn.tedu.demo2;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.Date;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
@Component
public class Employee {private String name="傻狍子";@Autowiredprivate Date date;@Overridepublic String toString() {return "Employee{" +"name='" + name + '\'' +", date=" + date +'}';}
}

3.测试案例

@Testpublic void testEmployee(){Employee employee = ctx.getBean("employee", Employee.class);System.out.println(employee);}

测试结果:输出当前系统时间,表示Date注入成功

Employee{name='傻狍子', date=Sat Oct 30 21:32:46 CST 2021}

案例:@Component 声明的组件注入到@Bean声明的组件

1.声明Bean类型

package cn.tedu.demo2;/*** @Author Mr WeiLiang* @Date 2021/8/5 0005 09:22* @Version 1.0*/
public class Dept {private String name="小良哥";private Employee manager;public void setManager(Employee manager){this.manager=manager;}@Overridepublic String toString() {return "Dept{" +"name='" + name + '\'' +", manager=" + manager +'}';}
}

2.在配置类Config中利用@Bean声明Bean组件

@Beanpublic Dept dept(Employee employee){Dept dept = new Dept();dept.setManager(employee);return dept;}

3.测试案例

@Testpublic void testDept(){Dept dept = ctx.getBean("dept", Dept.class);System.out.println(dept);}

测试结果

ept{name='小良哥', manager=Employee{name='傻狍子', date=Sat Oct 30 21:47:32 CST 2021}}

3 使用Properties文件

3.1 Druld 连接池

案例:

1. 导入连接池

2.配置Config.java

测试

测试结果

3.2 @PropertlesSource 和 Envlronment

案例:

3.3 @Value

利用@Value可以读取当前系统环境Environment中的信息,注入到变量中,这个方式更加灵活方便

Spring——DI相关推荐

  1. 一步一步手绘Spring DI运行时序图(Spring 自动装配之依赖注入)

    相关内容: 架构师系列内容:架构师学习笔记(持续更新) 一步一步手绘Spring IOC运行时序图一(Spring 核心容器 IOC初始化过程) 一步一步手绘Spring IOC运行时序图二(基于XM ...

  2. 手写Spring DI依赖注入,嘿,你的益达!

    手写DI 提前实例化单例Bean DI分析 DI的实现 构造参数依赖 一:定义分析 二:定义一个类BeanReference 三:BeanDefinition接口及其实现类 四:DefaultBean ...

  3. Spring DI[依赖注入]

    依赖注入(Dependency Injection,简称DI)意思是由容器或者框架将被调用类注入给调用对象,以此来降低调用对象和被调用类之间的依赖关系. 依赖注入主要有2种不同的实现形式: 1. 构造 ...

  4. Spring DI依赖注入讲解

    DI:dependency injection 依赖注入 在spring框架负责创建Bean对象时,动态将依赖对象注入到Bean组件. public class UserServiceImpl imp ...

  5. Java Spring DI之旅

    做过.NET的人很多都用过Microsoft Enterprise Library,里面有一个Dependency injection工具Unity,我们可以使用它来实现依赖注入:什么是依赖注入呢?我 ...

  6. Spring DI模式 小样例

           今儿跟同事讨论起来spring早期的,通过大篇幅xml的配置演变到今天annotation的过程,然后随手写了个小样例,感觉还不错,贴到这里留个纪念. 样例就是用JAVA API的方式, ...

  7. Spring DI(依赖注入)

    DI依赖注入 IoC(Inversion Of Control)控制翻转,Spring反向控制应用程序所需要使用的外部资源 DI(Dependency Injection)依赖注入,应用程序运行依赖的 ...

  8. Spring DI(依赖注入)注解篇

    1 课程内容介绍 我之前写的的一篇博客Spring核心功能DI(依赖注入)xml篇主要介绍了如何通过配置xml的方式来实现依赖注入,今天我们来介绍如何通过注解方式完成我们的依赖注入操作. 2 注入基本 ...

  9. Spring DI(依赖注入)构造器注入篇

    Spring 在不使用自动装配的方式进行注入需要我们必须为成员属性提供setter方法,这种方式相对比较繁琐,除了setter方法注入方式外,Spring还为我们提供了构造器配置的注入方式. 构造器默 ...

  10. Spring DI(依赖注入)Xml篇

    1 DI(依赖注入)简单介绍 如果您对Spring了解甚少,建议先移步我的另一篇博客Spring核心功能IOC之HelloWorld因为下面的内容是在该文章基础上进行阐述的 .我们可以通过一段简单代码 ...

最新文章

  1. java性能优化读书笔记(1)
  2. 数据分析能力到底有多重要
  3. jdk 9和jdk8_JDK 9是某些功能的终结
  4. 图论 —— 最短路 —— Floyd 算法
  5. JavaScript小效果的实现(笔记)
  6. Java Web学习总结(11)——Session使用示例教程
  7. 实现加载页Loading Page 的几种方法
  8. 2019118_四个化学数据分析(3)
  9. Python基础10—I/O编程
  10. [自学考试] [02142数据结构导论] Part1 概论
  11. 汇编dos系统调用(输入输出篇)
  12. PostScript文件
  13. 仿原生安卓文件管理器
  14. NetApp ADP (Advanced drive partitioning) 介绍
  15. android模拟器游戏大全,安卓模拟器游戏大全_小鸡模拟器
  16. Windows操作系统查看电脑开关机记录
  17. 学习Java可以做些什么?
  18. 面向对象:期待让我眼前一亮的你
  19. matlab中rowref的意思,Excel 中出现#REF是什么意思?(excel表格复制数据显示ref)
  20. 本地计算机上的OracleoraDB12Home1TNSListener服务启动后停止...

热门文章

  1. Dropbox + Farbox快速创建免费博客小站
  2. Chrome保存整个网页为图片、PDF
  3. 微软亚洲研究院2017年笔试编程题
  4. java pdf 盖章
  5. SringBoot实现PDF签字盖章
  6. 30岁测试员在一家公司工作八年后,告别“体制化”终于跳槽,别再妄想靠公司养老了!
  7. python相减函数subs,SUBS(subs是什么函数)
  8. matlab 纵坐标变为百分比形势,“怎么把excel纵坐标改为百分数类型“excel中如何求百分比...
  9. centos7.6 安装docker
  10. 猫和老鼠:博弈论——记忆化搜索