上篇中主要使用配置文件来定义一些类实例之间的组织关系,这篇所要做的就是将其扩展,实现支持自定义化的注解,也就是使用注解来完成配置类实例之间的组织关系。废话不多,请看配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="test" class="com.sample.spring1.egclasses.Test" single="true"/> <autoScan package="com.sample.spring1.egclasses"/> </beans>
此配置文件说明了我们框架将会扫描的范围。
再看一下我们自定义的几个annotation
package com.sample.spring1.annotations; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) public @interface AutoSet { public String id(); } package com.sample.spring1.annotations; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) public @interface Bean { public String id(); } package com.sample.spring1.annotations; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) public @interface Single { public boolean isSingle() default true; }
再看看我们用来测试的几个类
EgDao
package com.sample.spring1.egclasses; import com.sample.spring1.annotations.Bean; import com.sample.spring1.annotations.Single; @Bean(id="egDao") @Single(isSingle=true) public class EgDao { public void callMe() { System.out.println("Dao is called"); } }
EgSevice
package com.sample.spring1.egclasses; import com.sample.spring1.annotations.AutoSet; import com.sample.spring1.annotations.Bean; @Bean(id="service") public class EgSevice { @AutoSet(id="egDao") private EgDao egDao; public void callMe(){ egDao.callMe(); } public EgDao getEgDao() { return egDao; } }
EgService1
package com.sample.spring1.egclasses; import com.sample.spring1.annotations.AutoSet; import com.sample.spring1.annotations.Bean; @Bean(id="service1") public class EgSevice1 { @AutoSet(id="egDao") private EgDao egDao; public void callMe(){ egDao.callMe(); } public EgDao getEgDao() { return egDao; } }
ClassLoader 还试上文用到的并没有做什么特殊的处理
接下来就是我们框架的核心了
package com.sample.spring1; import java.io.File; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.net.URL; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdom2.input.SAXBuilder; import com.sample.spring1.annotations.AutoSet; import com.sample.spring1.annotations.Single; public class SampleSpringContainer { private static final Map<String,Bean> beans=new HashMap<String, Bean>(); static final Map<String,Object> singles=new HashMap<String, Object>(); static{ SAXBuilder sb = new SAXBuilder(); try { Document doc =sb.build(SampleSpringContainer.class.getClassLoader().getResourceAsStream("com/sample/spring1/springSample.xml")); Element rootElement = doc.getRootElement(); List<Element> beans = rootElement.getChildren("bean"); buidXmlBeans(beans); List<Element> AnnotactionBeans = rootElement.getChildren("autoScan"); if(!AnnotactionBeans.isEmpty()){ buildAnnotationBeans(AnnotactionBeans); } initBeans(); } catch (JDOMException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private static void buidXmlBeans(List<Element> beans){ for(Element bean :beans){ String id = bean.getAttributeValue("id"); if(SampleSpringContainer.beans.containsKey(id))continue; String clas = bean.getAttributeValue("class"); boolean single =Boolean.valueOf(bean.getAttributeValue("single")); Bean mbean=new Bean(clas, single); SampleSpringContainer.beans.put(id, mbean); List<Element> dependences = bean.getChildren("setProperty"); for(Element dependence :dependences){ String name = dependence.getAttributeValue("name"); String agr = dependence.getAttributeValue("refer"); Bean dbean2 = SampleSpringContainer.beans.get(agr); if(dbean2==null){ buidDependenceBeans(beans,agr); dbean2=SampleSpringContainer.beans.get(agr); } if(dbean2==null){ throw new IllegalArgumentException(id+"property "+name+"is not found"); } mbean.getDependence().put(name, dbean2); } } } private static void buildAnnotationBeans(List<Element> annotactionBeans) throws IOException { for(Element el:annotactionBeans){ String packgetName = el.getAttributeValue("package"); buildbyPackage(packgetName); } } private static void buildbyPackage(String packgetName) throws IOException { SampleClassLoader classLoader = SampleClassLoader.getClassLoader(); String fileResource = packgetName.replace('.', '/'); Enumeration<URL> resources = classLoader.getResources(fileResource); if(resources.hasMoreElements()){ URL url=resources.nextElement(); File file = new File(url.getFile()); for(String f:file.list()){ System.out.println(f); String[] split = f.split("\\."); if(split.length==1){ //TODO load sub package buildbyPackage(packgetName+"."+f); continue; } if(split.length<2)continue; if(split[1].equals("class")){ try { Class<?> loadClass = classLoader.loadClass(packgetName+"."+split[0]); Annotation[] classAnnotations = loadClass.getDeclaredAnnotations(); com.sample.spring1.annotations.Single isSingle=null; com.sample.spring1.annotations.Bean beanAn=null; for(Annotation an:classAnnotations){ if(an instanceof com.sample.spring1.annotations.Bean){ beanAn= (com.sample.spring1.annotations.Bean) an; continue; } if(an instanceof Single){ isSingle=(Single) an; } } if(beanAn!=null){ buildBean(loadClass,beanAn,isSingle); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } }else{ throw new IllegalArgumentException(packgetName+" can't be found!"); } } private static void buildBean(Class<?> loadClass, com.sample.spring1.annotations.Bean beanAn, Single isSingle) { Bean bean= new Bean(loadClass.getName(), isSingle==null?false:isSingle.isSingle()); SampleSpringContainer.beans.put(beanAn.id(), bean); Field[] fiels = loadClass.getDeclaredFields(); for(Field f:fiels){ Annotation[] annotations = f.getAnnotations(); AutoSet autoProperty=null; for(Annotation an:annotations){ if(an instanceof AutoSet){ autoProperty=(AutoSet) an; break; } } if(autoProperty!=null){ Bean bean2 = SampleSpringContainer.beans.get(autoProperty.id()); if(bean2==null){ Class<? extends Field> class1 = f.getClass(); Annotation[] classAnnotations = class1.getDeclaredAnnotations(); com.sample.spring1.annotations.Single isSinglePro=null; com.sample.spring1.annotations.Bean beanAnPro=null; for(Annotation an:classAnnotations){ if(an instanceof com.sample.spring1.annotations.Bean){ beanAnPro= (com.sample.spring1.annotations.Bean) an; continue; } if(an instanceof Single){ isSinglePro=(Single) an; } } if(beanAnPro!=null){ buildBean(class1,beanAnPro,isSinglePro); } bean2 = SampleSpringContainer.beans.get(autoProperty.id()); } bean.getDependence().put(f.getName(), bean2); } } } private static void initBeans() { for(Map.Entry<String, Bean> bean:beans.entrySet()){ if(!bean.getValue().getDependence().isEmpty()){ for(Map.Entry<String, Bean> dep:bean.getValue().getDependence().entrySet()){ deepBuildDependence(dep.getValue().getDependence()); } } singles.put(bean.getValue().getClassName(), bean.getValue().newInstance()); } } private static void deepBuildDependence(Map<String, Bean> dependence) { for(Map.Entry<String, Bean> dep:dependence.entrySet()){ Bean bean = dep.getValue(); if(!bean.getDependence().isEmpty()){ deepBuildDependence(bean.getDependence()); } singles.put(bean.getClassName(), bean.newInstance()); } } private static void buidDependenceBeans(List<Element> beans,final String rid){ for(Element bean :beans){ String id = bean.getAttributeValue("id"); if(!rid.equals(id))continue; String clas = bean.getAttributeValue("class"); boolean single =Boolean.valueOf(bean.getAttributeValue("single")); Bean mbean=new Bean(clas, single); SampleSpringContainer.beans.put(id, mbean); List<Element> dependences = bean.getChildren("setProperty"); for(Element dependence :dependences){ String name = dependence.getAttributeValue("name"); String agr = dependence.getAttributeValue("refer"); Bean dbean2 = SampleSpringContainer.beans.get(agr); if(dbean2==null){ buidDependenceBeans(beans,agr); dbean2=SampleSpringContainer.beans.get(agr); } if(dbean2==null){ throw new IllegalArgumentException(""); } mbean.getDependence().put(name, dbean2); } } } public static Object getBean(final String beanId){ Bean bean = beans.get(beanId); if(bean!=null){ if(bean.isSingle()){ return singles.get(beanId); }else{ return bean.newInstance(); } } return null; } } class Bean{ private String className; private boolean isSingle; public Bean(String className, boolean isSingle) { super(); this.className = className; this.isSingle = isSingle; } private Map<String,Bean> dependence=new HashMap<String, Bean>(); public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public boolean isSingle() { return isSingle; } public Map<String, Bean> getDependence() { return dependence; } public Object newInstance(){ SampleClassLoader classLoader = SampleClassLoader.getClassLoader(); Object newInstance=null; try { Class<?> loadClass = classLoader.loadClass(className); newInstance= loadClass.newInstance(); for(Map.Entry<String, Bean> entity:dependence.entrySet()){ Field field = loadClass.getDeclaredField(entity.getKey()); field.setAccessible(true); if(entity.getValue().isSingle()){ field.set(newInstance,SampleSpringContainer.singles.get(entity.getValue().getClassName())); }else{ field.set(newInstance, entity.getValue().newInstance()); } } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } return newInstance; } }
这个类是在上篇中的类在做了一些修改 实现了对annotation的支持
下面依旧,是个测试
package com.sample.spring1; import com.sample.spring1.egclasses.EgSevice; import com.sample.spring1.egclasses.EgSevice1; public class TestSpring { /** * @param args */ public static void main(String[] args) { EgSevice bean = (EgSevice) SampleSpringContainer.getBean("service"); bean.callMe(); EgSevice1 bean1 = (EgSevice1) SampleSpringContainer.getBean("service1"); bean1.callMe(); System.out.println(bean.getEgDao()==bean1.getEgDao()); } }
相关推荐
springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC...
本教程将聚焦于三个关键的框架概念:ORM(对象关系映射)、MVC(模型-视图-控制器)以及IOC( inversion of control,控制反转)。我们将探讨这些概念的基本原理,以及如何动手实现这些框架。 首先,让我们来深入...
在本项目中,我们将根据Spring的IoC原理,尝试实现自己的IoC框架。 首先,理解IoC的概念至关重要。IoC是指应用程序的控制权由传统的方式(如:对象直接创建和管理依赖关系)转移到框架或容器中,这样对象不再负责...
【IOC框架详解】 IOC(Inversion of Control)框架是一种软件设计模式,主要目的是为了降低对象间的耦合度,实现更好的可扩展性和可维护性。在传统的面向对象编程中,对象通常自行创建和管理它们所依赖的其他对象,...
### 多种IOC框架的比较 #### 概述 在软件开发领域,特别是.NET平台下,依赖注入(Inversion of Control, IOC)容器是管理对象生命周期和服务定位的关键工具。本文将对比分析几种主流的.NET IOC框架:Spring.NET、...
本教程将带你深入理解这两个概念,并通过手写一个简易的IoC和AOP框架来加深理解。 **依赖注入(IoC)** 依赖注入是Spring的核心特性之一,它允许开发者将对象的创建和管理权交给框架,从而降低组件之间的耦合度。在...
学习这个框架,开发者可以深入理解IOC和AOP的概念,掌握如何在C#中实现和使用这两种模式,提升自己的编程技巧和软件设计能力。同时,了解和使用开源框架,也有助于扩展视野,了解业界最佳实践。
2. **依赖注入**:这是IOC的主要实现方式,它允许我们在运行时将依赖关系注入到对象中,而不是在编译时硬编码。依赖注入有两种主要形式:构造函数注入、setter方法注入。通过这两种方式,对象可以在不自行创建依赖的...
Spring 框架系列(7)- Spring IOC 实现原理详解之 IOC 初始化流程 本文将详细解释 Spring 框架中的 IOC(Inversion of Control,控制反转)实现原理之 IOC 初始化流程。IOC 是一种软件设计模式,用于将软件系统中...
Android进阶——框架打造之IOC框架 实现通过Id找到控件的功能 实现通过Id找到Color、String资源 实现绑定view的点击事件、长按事件 实现绑定SetContentView 实现绑定网络的检测功能
### Spring IOC框架学习知识点 #### 一、Spring IOC框架简介 Spring框架是一个开源的企业级Java应用框架,它提供了丰富的功能来简化企业应用开发。其中,Inversion of Control (IoC)容器是Spring的核心特性之一,...
自己做的一个小型的IOC框架,希望大家一起研究下
在开发 Flex 应用程序时,Spring Actionscript IOC 框架和 Cairngorm MVC 模式结合使用,可以显著提升代码的可维护性和可扩展性。Spring Actionscript 是一个针对 Actionscript3 设计的轻量级框架,其灵感来源于 ...
Flex IOC(Inversion of Control)框架是用于构建可扩展且松耦合的ActionScript和Flex应用程序的工具。IOC,也称为依赖注入,是一种设计模式,它允许组件之间的依赖关系在运行时被管理,而不是在代码中硬编码。这种...
【 Castle 框架与 IOC 技术详解】 Castle框架是一个针对.NET平台的开源软件开发框架,它集合了多种成熟的应用技术,如ActiveRecord、AspectSharp、MonoRail以及MicroKernel/Windsor等。其中,MicroKernel是Castle的...
关于Spring框架中的IoC(控制反转)概念,我们可以通过一个幽默的例子来深入理解其核心思想。在编程领域,特别是面向对象编程中,控制反转(IoC)是一种设计原则,用于减少代码之间的耦合度,提高代码的可读性和可...
自己写了三个分别关于WEB,IOC,ORM的框架现将全部开源,内有说明文档,测试示例项目,框架源代码文件,sql语句等
轻量级的IOC框架,用于取代Spring在j2se项目中进行使用。
在Android开发中,IOC(Inversion of Control,控制反转)框架是提高代码可维护性和可扩展性的重要工具。本教程的下篇将深入探讨如何构建一个Android中的IOC框架,主要涉及的技术点包括依赖注入、注解处理以及反射...
标题 "动手写框架,模拟简易的Spring IOC" 暗示了这个压缩包包含了一个教程或实践项目,目的是帮助我们理解Spring框架的核心组件——控制反转(Inversion of Control,简称IOC)。Spring框架是Java开发中广泛使用的...