- 浏览: 139860 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
elephant_xiang:
condition例子,搞错了吧public void pro ...
jdk1.5的多线程总结一 -
yinlei126:
这么好的文章没有评论,谢谢
Mina框架剖析--动态篇 -
xds2008:
写的不错,值得表扬,测了一下,还不错,就是有点慢,但是最起码远 ...
java实现远程桌面监控 -
exp111:
这个确实很强 但是能不能连接一次不停的传呢 这个好像是必须连一 ...
java实现远程桌面监控 -
seeallsea:
不错!可以相互转换了。
keystore证书转换
产品的需求越来越多,则开发了越来越多的功能,同时也带来了越来越多的第三方library.这要是做server也就无所谓了,问题是我现在的这个东东,是个C/S的。看着Client里面越来越多的第三方jar,日益扩大的安装文件,这是个问题。
Client用到了Spring作为IOC容器来构造所有swing组件以及后台Bean,仔细分析了下,也就只用到了spring的IOC,最简单的Spring-core.jar都是好几百K。IOC的功能也不算很复杂,自己就尝试实现了一个简陋版的。
实现的原理其实很简单,第一步,java读取Spring格式的Bean配置文件,放入一个大的Map中;第二步,循环Map,根据存储信息,用反射依次生成这些实例,简单类型就直接赋值,需要ref Bean的就递归下去。如果是aop就用动态代理的方式来实现,最后都放入一个大的Map中。最后一步,反射调用配置的init方法,如果没配,就不管了。
首先是基本的结构
然后是读取配置加载到Map的片段:
再是反射加载类的片段:
到这里,所有的实例已经完整的加载到Map中去了。调用的时候直接用getBean()方法调用就可以了,就像Spring的ApplicationContext.getBean()一样。我就用这个在保持配置文件不变的情况下,将系统中用到Spring的地方全部去掉了,引用的lib从800多K降低到20多K,虽然实现得不完美,没有生命周期管理等,代码也写得不够优美,基本够用了。
Client用到了Spring作为IOC容器来构造所有swing组件以及后台Bean,仔细分析了下,也就只用到了spring的IOC,最简单的Spring-core.jar都是好几百K。IOC的功能也不算很复杂,自己就尝试实现了一个简陋版的。
实现的原理其实很简单,第一步,java读取Spring格式的Bean配置文件,放入一个大的Map中;第二步,循环Map,根据存储信息,用反射依次生成这些实例,简单类型就直接赋值,需要ref Bean的就递归下去。如果是aop就用动态代理的方式来实现,最后都放入一个大的Map中。最后一步,反射调用配置的init方法,如果没配,就不管了。
首先是基本的结构
public class Bean { private String id;//bean的id,对应配置中的id private String type;//bean的类型,对应配置中的class private String init;//init方法的名字,对应配置中的init private boolean singlton = true;//是否是单例,对应配置中的singlton private Map mProperty = new HashMap();//Bean内部的<property>配置 private List constructorList = new ArrayList();//构造器的列表,对应<constructor-arg>配置 private Object bean;//真正的Bean实例 ......
然后是读取配置加载到Map的片段:
public static Map loadXml(String fileName) { fileName = Thread.currentThread().getContextClassLoader().getResource( fileName).getPath().substring(1); log.log(Level.FINE, "load xml:" + fileName); Map<String, Bean> beansMap = new HashMap<String, Bean>(); DocumentBuilder documentBuilder; try { documentBuilder = getDocumentBuilder(); Document document = documentBuilder.parse(new File(fileName)); Element root = document.getDocumentElement(); NodeList childList = selectNodes("/beans/bean", root); for (int i = 0; i < childList.getLength(); i++) { Element currentNode = (Element) childList.item(i); switch (currentNode.getNodeType()) { case Node.TEXT_NODE: break; case Node.ELEMENT_NODE: Bean bean = new Bean(); String beanId = currentNode.getAttribute("id").trim(); String beanType = currentNode.getAttribute("class").trim(); if(null != currentNode.getAttributes().getNamedItem("init-method")) { bean.setInit(currentNode.getAttributes().getNamedItem("init-method").getNodeValue()); } if(null != currentNode.getAttributes().getNamedItem("singlton")) { bean.setSinglton(new Boolean(currentNode.getAttributes().getNamedItem("singlton").getNodeValue()).booleanValue()); } bean.setId(beanId); bean.setType(beanType); NodeList children = currentNode.getChildNodes(); for (int j = 0; j < children.getLength(); j++) { if (children.item(j).getNodeType() == Node.TEXT_NODE) { continue; } Element properties = (Element) children.item(j); if (properties.getNodeName().equals("property")) { String name = properties.getAttribute("name"); Element element = getElement(properties); if (element == null) { continue; } if (element.getNodeName().equals("value")) { bean.getMProperty().put(name, getTextValue(element)); } else if (element.getNodeName().equals("ref")) { String[] refString = new String[] { element .getAttribute("bean") }; bean.getMProperty().put(name, refString); } else if (element.getNodeName().equals("list")) { List valuesList = new ArrayList(); NodeList values = element.getChildNodes(); for (int k = 0; k < values.getLength(); k++) { if (values.item(k).getNodeType() == Node.TEXT_NODE) { continue; } Element valueP = (Element) values.item(k); if (valueP.getNodeName().equals("value")) { valuesList.add(getTextValue(valueP)); } else if (valueP.getNodeName().equals( "ref")) { valuesList.add(new String[] { valueP .getAttribute("bean") }); } } bean.getMProperty().put(name, valuesList); } else if (element.getNodeName().equals("props")) { Map propertiesMap = new LinkedHashMap(); NodeList entries = element.getChildNodes(); for (int k = 0; k < entries.getLength(); k++) { if (entries.item(k).getNodeType() == Node.TEXT_NODE) { continue; } Element entry = (Element) entries.item(k); String key = entry.getAttribute("key"); String value = getTextValue(entry); propertiesMap.put(key, value); } bean.getMProperty().put(name, propertiesMap); } } else if (properties.getNodeName().equals( "constructor-arg")) { Constructs constructs = new Constructs(); if (null != properties.getAttributes().getNamedItem("value")) { constructs.setValue(properties.getAttributes().getNamedItem("value").getNodeValue()); if (null != properties.getAttribute("type")) { constructs.setType(properties .getAttribute("type")); } bean.getConstructorList().add(constructs); } else { Element refE = getElement(properties); constructs.setValue(new String[] { refE .getAttribute("bean") }); bean.getConstructorList().add(constructs); } } } beansMap.put(beanId, bean); break; } } } catch (Exception e) { throw new BeanException(e); } return beansMap;
再是反射加载类的片段:
private void initFactory() { Iterator itr = beansMap.entrySet().iterator(); while(itr.hasNext()) { Entry entry = (Entry)itr.next(); Object obj = getBean((String)entry.getKey()); Bean bean = (Bean)entry.getValue(); if(null != bean.getInit()) { log.info("Now init bean:[" + (String)entry.getKey() + "] type[" + bean.getType()+"]"); //有init方法就反射调用 Util.initMethod(bean, obj); } } } /** * 根据名字获取Bean,有就直接获取没有就加载再返回 * @param beanName * @return */ public Object getBean(String beanName) { Bean bean = (Bean) beansMap.get(beanName); if(bean.isSinglton()) { return null == bean.getBean() ? generatObj(bean) : bean.getBean(); } else { return generatObj(bean); } } /** * 加载Bean * @param bean * @return */ private Object generatObj(Bean bean) { String beanType = bean.getType(); Object obj = null; //先根据构造器初始化 if(bean.getConstructorList().size() > 0) { Object[] parameters = new Object[bean.getConstructorList().size()]; Class[] clazz = new Class[bean.getConstructorList().size()]; for(int i = 0;i < bean.getConstructorList().size();i++) { Constructs arg = (Constructs)bean.getConstructorList().get(i); if(arg.getValue() instanceof String) { parameters[i] = Util.switchValue((String)arg.getValue(),arg.getType()); } else if(arg.getValue() instanceof String[]) { parameters[i] = getBean(((String[]) arg.getValue())[0]); } clazz[i] = parameters[i].getClass(); } obj = Util.newInstance(beanType,clazz,parameters); } //没有就直接初始化 if(null == obj){ obj = Util.newInstance(beanType); } if(bean.isSinglton()) { bean.setBean(obj); } //aop的配置就用动态代理方式 if (obj instanceof ProxyFactoryBean) { obj = getProxyBean(bean, obj); } else { setProperty(bean, obj); } if(bean.isSinglton()) { bean.setBean(obj); } return obj; } //加载动态代理类 private Object getProxyBean(Bean bean, Object obj) { Map propertiesMap = bean.getMProperty(); Iterator keysIterator = propertiesMap.keySet().iterator(); String interfaceClass = null; Object beanObj = null; while (keysIterator.hasNext()) { String proxyProperty = (String) keysIterator.next(); Object proxyValue = propertiesMap.get(proxyProperty); // value if (proxyValue instanceof String) { interfaceClass = (String) proxyValue; } else if (proxyValue instanceof String[]) { String[] strsValue = (String[]) proxyValue; if (strsValue.length == 1) { String beanId = ((String[]) proxyValue)[0]; beanObj = getBean(beanId); Util.setProperty(obj, proxyProperty, beanObj); } } else if (proxyValue instanceof List) { Iterator valuesIterator = ((List) proxyValue).iterator(); List valuesList = new ArrayList(); while (valuesIterator.hasNext()) { Object value = valuesIterator.next(); if (value instanceof String) { valuesList.add(getBean((String) value)); } } Util.setProperty(obj, proxyProperty, valuesList); } } if (null != interfaceClass && null != beanObj) { if (!Util.includeInterfaceOrnot(beanObj, interfaceClass)) { throw new BeanException("no interface implemented "); } } Object proxyBean = ((ProxyFactoryBean) obj).getProxyObject(); return proxyBean; } //设置类的property private void setProperty(Bean bean, Object obj) { Map propertiesMap = bean.getMProperty(); Iterator keysIterator = propertiesMap.keySet().iterator(); while (keysIterator.hasNext()) { String property = (String) keysIterator.next(); Object value = propertiesMap.get(property); if (value instanceof String) { Util.setProperty(obj, property, (String) value); } else if (value instanceof String[]) { String[] strsValue = (String[]) value; if (strsValue.length == 1) { String beanId = ((String[]) value)[0]; Util.setProperty(obj, property, getBean(beanId)); } } else if (value instanceof List) { Iterator valuesIterator = ((List) value).iterator(); List valuesList = new ArrayList(); while (valuesIterator.hasNext()) { Object valueList = (Object) valuesIterator.next(); if (valueList instanceof String[]) { // ref valuesList.add(getBean(((String[]) valueList)[0])); } } Util.setProperty(obj, property, valuesList); }else if (value instanceof Map) { Util.setProperty(obj, property, value); } } }
到这里,所有的实例已经完整的加载到Map中去了。调用的时候直接用getBean()方法调用就可以了,就像Spring的ApplicationContext.getBean()一样。我就用这个在保持配置文件不变的情况下,将系统中用到Spring的地方全部去掉了,引用的lib从800多K降低到20多K,虽然实现得不完美,没有生命周期管理等,代码也写得不够优美,基本够用了。
发表评论
-
Java上clear Squid缓存
2011-11-29 10:26 1282实现原理: 构造TCP请求,调用Squid自带 ... -
HttpURLConnection设置代理
2011-01-21 11:00 1466设置全局代理,JVM范围内有效: System ... -
JCE provider管理的问题
2010-08-23 13:24 3249现象 两个module A和B分别采用了infosec的不同版 ... -
Jar冲突解决二
2010-08-23 11:54 1745方案思想 自定义CustomClassLoader,彻底改变c ... -
Jar冲突解决一
2010-08-23 10:46 1226目的是classpath中线性的jar排列扩展成树型排列。方案 ... -
负载均衡备注二
2010-03-30 11:41 1091Lvs或者F5的负载体系中 ... -
SelectableChannel关闭注意事项
2010-03-29 11:49 997SocketChannel和ServerSocketChann ... -
java clone备忘
2009-12-09 14:39 8191.Object clone 就是复制一个对象的复本,在Fac ... -
远程调用之RMI
2009-05-22 00:03 1047RMI(Remote Method Invocation ... -
Java修饰符归纳
2009-05-20 17:26 924final 1.final类 final类不能被继承, ... -
classloader整理
2009-05-18 18:08 1115classloader它就是用来加载Class文件到JV ... -
Java IO归纳
2009-05-17 14:39 1652Java的IO基于装饰器模式设计。根接口是InputS ... -
java实现远程桌面监控
2009-05-10 19:28 3854java里面的Robot类可以完成截图的功能,借助于这 ... -
Java也可以截图
2009-05-10 14:48 1116java.awt.Robot类真的很好玩。玩Robot会给你带 ... -
jdk1.5的多线程总结二
2009-05-10 13:07 1600新的Synchronizer: Java 5.0里新加了4个协 ... -
jdk1.5的多线程总结一
2009-05-10 01:17 6034Java 5.0里新加入了三个多线程包:java.util.c ... -
JavaGC知识整理
2009-05-08 00:55 963堆 JVM管理的内存叫堆。在32Bit操作系统上有1.5G-2 ... -
ConcurrentHashMap
2009-05-08 00:54 1023实现原理 锁分离 (Lock Stripping) C ... -
Java Socket异常整理
2009-05-08 00:41 3545最近跟进性能测试,碰 ... -
Java各种路径和参数
2009-05-08 00:39 12461.JSP中获得当前应用的 ...
相关推荐
8. **集成性**:Spring 不重新发明轮子,它支持与其他流行框架和库的集成,如 Hibernate、MyBatis 等,提供了一站式解决方案,使得开发者可以专注于业务需求,而不是技术细节。 【IOC(Inversion of Control,控制...
sunflower-ioc这是一个基于注解的简易ioc工具, 为什么要重复造轮子呢, 只是为了好玩.:beaming_face_with_smiling_eyes:用法在Class上使用@Bean标注一个对象需要容器管理;在Field上使用@Resource标注依赖, 该field...
下面,我们将深入探讨如何在Struts 2中实现IoC,并具体讲解其历史背景、实现步骤以及为何选择Spring作为IoC容器。 ### 历史背景 Struts 2框架源自WebWork,WebWork 2.2之前,其内部实现了一套控制反转机制。然而,...
控制反转(IOC)是一种设计原则,它将对象的创建和管理责任从对象自身转移到外部容器,即Spring的IoC容器。在传统编程中,对象通常自行创建所需的依赖对象,而在IOC中,这些依赖是由容器在运行时动态地注入到对象中...
- IoC 是指对象之间的依赖关系由容器来建立,而不是由对象自身来建立。 - 这有助于降低对象间的耦合度。 - **3.2 依赖注入 (DI)** - DI 是 IoC 的具体实现方式,容器通过调用对象的 setter 方法或构造器来建立...
- **IoC容器**:Inversion of Control (IoC) 容器是Spring的核心组件之一,负责管理对象的生命周期和配置。 - **AOP(面向切面编程)**:Spring提供了对AOP的支持,这有助于分离横切关注点(如日志记录、事务管理等...
- **轮子理论**:Spring框架推崇“轮子理论”,即避免重复发明已有的组件或功能,而是尽可能地利用现有的成熟技术和工具。 - **宗旨**:Spring框架的宗旨在于不重新发明技术,而是让现有技术更加易用,提升开发效率...
它的核心目标是使开发过程变得简单,通过POJO(Plain Old Java Object)编程模型来促进良好的编程实践。Spring以其非侵入性著称,即它允许开发者在不依赖特定框架的情况下使用Java进行开发。尽管Spring本身是轻量级...
1.spring:给软件行业带来了春天; 2.spring的理念:spring框架的初衷是使的现有的更加实用,spring不是创造轮子(技术或框架),而是... Ioc容器:控制反转; Aop:面向切面编程; 对事务的支持; 对矿建的支持;
例如,在阿里巴巴早期的系统中,可以看到各种Factory的使用,而Spring的IoC容器可以更优雅地管理这些对象的创建和依赖。 **面向切面编程(AOP)** AOP是Spring提供的一种处理横切关注点(如日志、事务管理)的方法...
RCP使开发人员可以集中精力进行应用程序业务代码的开发,而不需要花费时间重新发明轮子编写应用程序管理的逻辑。反转控制(InversionofControl,IoC)和依赖注入(DependencyInjection,DI)是两种编程模式,可用于减少...
IoC使得对象的依赖关系由容器管理,而不是由对象自身负责,从而降低了耦合度。AOP则允许将系统级服务如日志、事务管理等与业务逻辑分离,提高了代码的可维护性和可复用性。 Spring框架不仅仅是一个简单的服务器端...
- Struts2采用XWork核心,提供了前端拦截机(interceptor)、运行时表单属性验证、类型转换、表达式语言(OGNL)和IoC(控制反转)容器等功能。 3. Struts2框架在Web开发中的应用 - Struts2框架是在Java Web开发...
today-web框架2.0刚出来时没有ioc容器感觉不是很方便,所以想自己实现一个。 :anxious_face_with_sweat:完全懵逼。之前学过怎么用Spring但是对他的完全完全不了解的我带着试一试的心态开始到处查资料,就这样我又...
在CommonLibrary.NET中,可能包含了一套自定义的IOC容器,它能帮助开发者解耦代码,提高代码的可测试性和可维护性。 3. 验证扩展:验证是应用程序中不可或缺的一环,用于确保输入数据的有效性和安全性。这个库可能...
Spring的核心是IOC(Inversion of Control)容器,负责管理对象的生命周期和装配。此外,Spring还支持事务管理、数据访问集成、Web MVC框架等,使得开发者能方便地整合各种技术,如Hibernate。 3. **Hibernate**: ...
Spring Framework的核心特性包括IoC容器、AOP、数据访问/集成、事务管理等。 ##### 3.4 Spring Cloud Spring Cloud是一个基于Spring Boot实现的云应用开发工具包,它提供了微服务架构所需的一系列服务治理组件,...
在Spring中,依赖注入是通过IoC容器实现的,IoC容器负责管理Bean的实例化、依赖解析以及生命周期。 ##### 2.3 AOP面向切面编程 除了依赖注入外,Spring还支持面向切面编程(AOP)。AOP是一种编程范式,用于分离横切...