spring进阶二
来源:互联网 发布:济南易途java培训骗局 编辑:程序博客网 时间:2024/06/08 10:37
上篇博文【SSH进阶之路】一步步重构容器实现Spring框架——从一个简单的容器开始(八),我们为了去掉接口
对具体实现的依赖关系,封装了一个特别简陋的容器,最后给大家抛出了一个问题:如何让组件不再依赖容器?这篇
博文主要是通过两种解决方案来解决这个问题,最后对比各自的优缺点。
服务定位器
解决方案之一就是使用服务定位器(Service Locator),我们也可以叫主动查找。服务定位器用来封装复杂的查
找逻辑,同时对外开放简单的查找方法,所有组件都可以将查找请求委派给服务定位器。
服务定位器可是一个简单的类,也可以是一种复杂的机制,如JNDI。不同的容器有着不同的查找机制。
下面是一个简单的服务定位器:
- public class ServiceLocator {
- static{
- //该类加载的时候执行一次
- Container.init();
- }
- public static Object getDao(){
- return Container.getComponent("dao4Mysql");
- // return Container.getComponent("dao4Oracle");
- }
- }
- import com.tgb.container.ServiceLocator;
- import com.tgb.container.dao.Dao;
- import com.tgb.container.service.Service;
- public class ServiceImpl implements Service {
- // 从服务器定位器查找所需的接口
- private Dao dao = (Dao) ServiceLocator.getDao();;
- @Override
- public void serviceMethod() {
- dao.daoMethod();
- }
- }
原先由ServiceImpl到Container的依赖线上添加了ServiceLocator,组件不再直接依赖于容器,实现了“非侵入
式”管理。
控制反转(IoC)
解决方案之二就是使用控制反转,我们将控制权交给容器,在运行期才由容器决定将具体的实现动态的“注入”到
调用类的对象中。
Ioc是一种通用的设计原则,DI(依赖注入)则是具体的设计模式。依赖注入有三种方式,我们使用的是Setter注入。
修改Service接口:
- import com.tgb.container.dao.Dao;
- public interface Service {
- //增加注入接口的方法
- public void setDao(Dao dao);
- public void serviceMethod();
- }
- import com.tgb.container.dao.Dao;
- import com.tgb.container.service.Service;
- public class ServiceImpl implements Service {
- private Dao dao;
- //依赖注入
- public void setDao(Dao dao) {
- this.dao= dao;
- }
- @Override
- public void serviceMethod() {
- dao.daoMethod();
- }
- }
- import java.util.HashMap;
- import java.util.Map;
- import com.tgb.container.dao.Dao;
- import com.tgb.container.dao.impl.Dao4MySqlImpl;
- import com.tgb.container.service.Service;
- import com.tgb.container.service.impl.ServiceImpl;
- public class Container {
- private static Map<String, Object> components;
- private Container() {
- }
- /**
- * 初始化容器
- */
- public static synchronized void init() {
- if (components == null) {
- components = new HashMap<String, Object>();
- //写一个读配置文件的类,根据读取的配置文件,反射对应的类
- //反射好类后进行 依赖管理,往对应的属性上注入相应的类
- Dao dao4Mysql = new Dao4MySqlImpl();
- components.put("dao4Mysql", dao4Mysql);
- Service service = new ServiceImpl();
- components.put("service", service);
- //容器维护依赖关系
- service.setDao(dao4Mysql);
- }
- }
- /**
- * 查找组件
- *
- * @param id
- * @return
- */
- public static Object getComponent(String id) {
- return components.get(id);
- }
- }
由ServiceImpl到Container的依赖线可以直接抹掉了!
Setter注入易于使用,但是会有安全问题。第一次注入之后,有可能再一次调用setter方法,改变了原有的依赖。
这种对依赖的无意修改会带来无法预料的后果。所以需要有安全检查机制。
对比
解决组件不再依赖容器,我们使用了两种方案:服务定位器和控制反转。
1、使用服务定位器查找组件,这是一种主动查找的行为。这种查找有一个缺点:组件需要知道如何查找资源。组件和容器依赖变成了组件和服务定位器的依赖。
2、然后,我们使用了控制反转,这是一种被动查找的行为。容器主动将资源推送给组件,组件则以一种合适的方式来接受资源。反转资源获取方向,这就是大名鼎鼎的Ioc(控制反转)。
从类图中我们可以发现,容器需要知道各个组件,容器和组件的耦合度还是很高的,下篇博文【SSH进阶之路】
一步步重构容器实现Spring框架——配置文件+反射实现IoC容器(十),我们利用配置文件+反射进一步降低耦合度。
- spring进阶二
- spring进阶(二)事务
- spring进阶
- Spring进阶
- redis实现 spring-redis-data初学习二 进阶,存取对象
- Spring进阶—如何用Java代码实现邮件发送(二)
- Spring Data MongoDB 五:进阶文档查询(分页、Morphia)(二)
- java web学习(进阶篇)二 Spring里的Bean
- Spring Data MongoDB 五:进阶文档查询(分页、Morphia)(二)
- spring框架学习之路(二)-进阶技能(1)-数据库连接池和事务管理
- spring框架学习之路(二)-进阶技能(2)-邮件发送
- spring框架学习之路(二)-进阶技能(3)-定时器任务
- Spring进阶(一)
- Spring MVC 进阶1
- Spring进阶学习一
- 3.spring进阶运用
- Spring进阶 之简介
- spring进阶三
- 巧用onWindowFocusChanged(boolean hasFocus)
- 日志Human Resource Evaluation
- Storm实时计算:流操作入门编程实践
- 十道海量数据处理面试题
- 内存泄露与野指针
- spring进阶二
- 导出excel功能(解决大数据量问题)
- java设计模式之适配器模式
- 【移动前端开发实践】从无到有(统计、请求、MVC、模块化)H5开发须知
- flume-1.4.0整合hbase-0.98.0实战数据采集,同时将采集到的数据放入hbase和h
- iOS 获取手机设备IP地址的两种方法
- opencv2学习(1)
- Oracle 触发器语法及实例
- 有NSString的截取