Spring——DI
一 依赖注入
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组件注入时候组件自动匹配规则:
- 首先按照注入参数类型查找相应类型的Bean组件,如果没有直接报错误
- 如果在是spring容器中能够匹配上唯一类型的Bean组件,则进行注入成功
- 如果按照类型匹配到两个bean组件,则查找组件ID和变量名是否匹配,如果匹配则注入成功
- 如果组件类型和组件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相关推荐
- 一步一步手绘Spring DI运行时序图(Spring 自动装配之依赖注入)
相关内容: 架构师系列内容:架构师学习笔记(持续更新) 一步一步手绘Spring IOC运行时序图一(Spring 核心容器 IOC初始化过程) 一步一步手绘Spring IOC运行时序图二(基于XM ...
- 手写Spring DI依赖注入,嘿,你的益达!
手写DI 提前实例化单例Bean DI分析 DI的实现 构造参数依赖 一:定义分析 二:定义一个类BeanReference 三:BeanDefinition接口及其实现类 四:DefaultBean ...
- Spring DI[依赖注入]
依赖注入(Dependency Injection,简称DI)意思是由容器或者框架将被调用类注入给调用对象,以此来降低调用对象和被调用类之间的依赖关系. 依赖注入主要有2种不同的实现形式: 1. 构造 ...
- Spring DI依赖注入讲解
DI:dependency injection 依赖注入 在spring框架负责创建Bean对象时,动态将依赖对象注入到Bean组件. public class UserServiceImpl imp ...
- Java Spring DI之旅
做过.NET的人很多都用过Microsoft Enterprise Library,里面有一个Dependency injection工具Unity,我们可以使用它来实现依赖注入:什么是依赖注入呢?我 ...
- Spring DI模式 小样例
今儿跟同事讨论起来spring早期的,通过大篇幅xml的配置演变到今天annotation的过程,然后随手写了个小样例,感觉还不错,贴到这里留个纪念. 样例就是用JAVA API的方式, ...
- Spring DI(依赖注入)
DI依赖注入 IoC(Inversion Of Control)控制翻转,Spring反向控制应用程序所需要使用的外部资源 DI(Dependency Injection)依赖注入,应用程序运行依赖的 ...
- Spring DI(依赖注入)注解篇
1 课程内容介绍 我之前写的的一篇博客Spring核心功能DI(依赖注入)xml篇主要介绍了如何通过配置xml的方式来实现依赖注入,今天我们来介绍如何通过注解方式完成我们的依赖注入操作. 2 注入基本 ...
- Spring DI(依赖注入)构造器注入篇
Spring 在不使用自动装配的方式进行注入需要我们必须为成员属性提供setter方法,这种方式相对比较繁琐,除了setter方法注入方式外,Spring还为我们提供了构造器配置的注入方式. 构造器默 ...
- Spring DI(依赖注入)Xml篇
1 DI(依赖注入)简单介绍 如果您对Spring了解甚少,建议先移步我的另一篇博客Spring核心功能IOC之HelloWorld因为下面的内容是在该文章基础上进行阐述的 .我们可以通过一段简单代码 ...
最新文章
- java性能优化读书笔记(1)
- 数据分析能力到底有多重要
- jdk 9和jdk8_JDK 9是某些功能的终结
- 图论 —— 最短路 —— Floyd 算法
- JavaScript小效果的实现(笔记)
- Java Web学习总结(11)——Session使用示例教程
- 实现加载页Loading Page 的几种方法
- 2019118_四个化学数据分析(3)
- Python基础10—I/O编程
- [自学考试] [02142数据结构导论] Part1 概论
- 汇编dos系统调用(输入输出篇)
- PostScript文件
- 仿原生安卓文件管理器
- NetApp ADP (Advanced drive partitioning) 介绍
- android模拟器游戏大全,安卓模拟器游戏大全_小鸡模拟器
- Windows操作系统查看电脑开关机记录
- 学习Java可以做些什么?
- 面向对象:期待让我眼前一亮的你
- matlab中rowref的意思,Excel 中出现#REF是什么意思?(excel表格复制数据显示ref)
- 本地计算机上的OracleoraDB12Home1TNSListener服务启动后停止...
热门文章
- Dropbox + Farbox快速创建免费博客小站
- Chrome保存整个网页为图片、PDF
- 微软亚洲研究院2017年笔试编程题
- java pdf 盖章
- SringBoot实现PDF签字盖章
- 30岁测试员在一家公司工作八年后,告别“体制化”终于跳槽,别再妄想靠公司养老了!
- python相减函数subs,SUBS(subs是什么函数)
- matlab 纵坐标变为百分比形势,“怎么把excel纵坐标改为百分数类型“excel中如何求百分比...
- centos7.6 安装docker
- 猫和老鼠:博弈论——记忆化搜索