Ioc、DI
引入
实现某功能的方法:
- 面向对象
- 类与类存在调用关系
- 存在依赖,高耦合
- 分离接口
- 将被调用的类作为接口实现
- 通过调用接口来调用类
- 降低耦合度(依赖)
- 容器实现
- 将类与接口的实现类放入容器中,通过容器来获取
- 实现了解耦
- 问题:
- Container容器对所管理的所有组件产生了依赖
- 类对容器产生依赖,封装具有查找逻辑
- 服务定位器 (JNDI) (体现了IOC原则)
- 封装查找逻辑,对外公开查找组件的方法
- 应用服务定位器将查找逻辑从组件里分离出来
- 降低组件在查找方面的复杂性
- 增加组件的重用性
- 局限性:组件必须知道怎么找资源
- 封装查找逻辑,对外公开查找组件的方法
- 控制反转(根据 3.容器实现 进行Ioc)(体现了IOC原则)
- 不需要服务定位器
- 由容器将组件注入到另一个组件
- 完全面向接口
概念
Ioc 控制反转 [Inversion of Control]
目的:设计原则,解耦组件之间的依赖关系。降低耦合度
好处:
- 从主动获取资源变成 被动接收
- 查找的被动形式
B、C类具有相同的方法、不同的实现。A类需要调用B或C类的方法
- 主动:A类主动获取B或C的对象,想要谁要谁
- 被动:容器给A类哪个类,A类就必须用哪个类
聪明的小伙伴应该已经理解了,没错,就是自由恋爱和包办婚姻的区别。
DI 依赖注入 [Dependency Injection]
具体的设计模式,体现Ioc设计原则
DI是Ioc的最典型的实现,不能混用
DI用法
DI 依赖注入的类型
- 接口注入
setter
注入[Spring实现]- 缺点:会忘记注入
- 抛出空指针
- 构造器注入[Spring实现]
- 避免了
setter
注入 的缺点 - 没有明确含义的方法名,对参数位置、数量有要求
- 避免了
流行程度最广
setter
注入
框架
什么是框架
已经对基础的代码进行了封装并提供相应的API,开发者在使用框架是直接调用封装好的api可以省去很多代码编写,从而提高工作效率和开发速度。
框架
- netty
- mina
- luence
Spring框架
创作人:Rod Johnson
Spring Ioc容器
Spring容器体现了IoC原理
Spring容器通过读取配置元数据负责对Beans实例化、配置、装配
Beanfactory
简介
- 提供一个先进配置机制,能够管理任何类型的对象
- 负责对Bean对象实例化、装配、生命周期的管理
实现Beanfactory
- Beanfactory为接口,需要用
XmlBeanFactory
实现类 XmlBeanFactory
需传入一个Resource实例ClassPathResource
FileSystemResource
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
- 从BeanFactory获取Bean实例
MyBean bean = (MyBean)factory.getBean("myBean");
ApplicationContext
简介
ApplicationContext
是 Beanfactory
的子接口,提供更多更全面的功能
添加了更多的企业特定的功能
- 更方便的集成Spring的AOP功能
- 消息资源处理
- 事件的发布
实现类
ClassPathXmlApplication
xml通过路径FileSystemXmlApplication
xml放在文件系统中XmlWebApplicationContext
基于web程序的xml实现类AnnotationConfigApplicationContext
注解
BeanFactory
和ApplicationContext
区别:
BeanFactory
提供了配置框架和基本功能,ApplicationContext
添加了更多的企业特定功能ApplicationContext
是BeanFactory
的一个子接口,也是一个完整的超集- 两者实例化Bean的载入方式不同
BeanFactory
延迟载入所有Bean,直到getBean()
方法调用时才被创建ApplicationContext
启动后载入所有单例Bean,通过预载入单实例Bean,确保当需要时使用
配置元数据
元数据:通过容器使用配置来反应Beans和他们之间的依赖关系
-
基于Xml的配置
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- xml配置 -->
<!-- id叫什么都可以 -->
<!-- class为完整的包名+类名 -->
<bean id="IntelCpu" class="com.pc.IntelCpu"></bean>
<!-- 依赖注入 -->
<!-- ref对应依赖注入id -->
<bean id="Computer" class="com.pc.Computer">
<property name="cpu" ref="IntelCpu"></property>
</bean>
</beans>
-
基于注解的配置
在xml文件中进行注解配置
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 注解配置 -->
<context:annotation-config />
<context:component-scan base-package="com.pc"></context:component-scan>
</beans>
在类中加入注解
类 | 注解 |
---|---|
依赖组件类 | @Component |
调用依赖类 | @Component("Computer") |
依赖组件 | @Resource |
@@Component
默认将类名小写,可以通过@Component("Computer")进行自定义
-
基于java的配置
注解类的注解不变
在测试类注解
@Configuration
@ComponentScan("包名")
调用
ApplicationContext ac = new AnnotationConfigApplicationContext();
//类 class = (类)ac.getBean("注解的类名字");
//class.方法();
每日英语(误)
annotation 注解
application 应用
component 组件
config 配置
configuration 配置
context 上下文环境
property 财产、所有权
scan 扫描、浏览