<?xml version="1.0" encoding="GBK"?> <beans> <bean id="computer" class="lee.Computer"> <!-- 为name注入基本类型的值 --> <property name="name" value="孙悟空的电脑"/> <!-- 为out注入容器中其他Bean --> <property name="out" ref="betterPrinter"/> </bean> <!-- 配置两个Bean实例 --> <bean id="printer" class="lee.Printer"/> <bean id="betterPrinter" class="lee.BetterPrinter"/> <!-- 配置一个prototype行为的Bean实例 --> <bean id="now" class="java.util.Date" scope="prototype"/> <!--①--> </beans>
<?xml version="1.0" encoding="GBK"?> <project name="hibernte" basedir="." default=""> <property name="src" value="src"/> <property name="dest" value="classes"/> <path id="classpath"> <fileset dir="lib"> <include name="*.jar"/> </fileset> <pathelement path="${dest}"/> </path> <target name="compile" description="Compile all source code"> <delete dir="${dest}"/> <mkdir dir="${dest}"/> <copy todir="${dest}"> <fileset dir="${src}"> <exclude name="**/*.java"/> </fileset> </copy> <javac destdir="${dest}" debug="true" deprecation="false" optimize="false" failonerror="true"> <src path="${src}"/> <classpath refid="classpath"/> </javac> </target> <target name="run" description="Run the main class" depends="compile"> <java classname="lee.IoCTest" fork="yes" failonerror="true"> <classpath refid="classpath"/> </java> </target> </project>
package lee; /** * Description: * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> * <br/>Copyright (C), 2001-2016, Yeeku.H.Lee * <br/>This program is protected by copyright laws. * <br/>Program Name: * <br/>Date: * @author Yeeku.H.Lee kongyeeku@163.com * @version 1.0 */ public class BetterPrinter implements Output { private String[] printData = new String[MAX_CACHE_LINE * 2]; // 用以记录当前需打印的作业数 private int dataNum = 0; public void out() { // 只要还有作业,继续打印 while(dataNum > 0) { System.out.println("高速打印机正在打印:" + printData[0]); // 把作业队列整体前移一位,并将剩下的作业数减1 System.arraycopy(printData , 1, printData, 0, --dataNum); } } public void getData(String msg) { if (dataNum >= MAX_CACHE_LINE * 2) { System.out.println("输出队列已满,添加失败"); } else { // 把打印数据添加到队列里,已保存数据的数量加1。 printData[dataNum++] = msg; } } }
package lee; /** * Description: * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> * <br/>Copyright (C), 2001-2016, Yeeku.H.Lee * <br/>This program is protected by copyright laws. * <br/>Program Name: * <br/>Date: * @author Yeeku.H.Lee kongyeeku@163.com * @version 1.0 */ public class Computer { private Output out; private String name; public Computer(){} // out的setter和getter方法 public void setOut(Output out) { this.out = out; } // name的setter和getter方法 public void setName(String name) { this.name = name; } // 定义一个模拟获取字符串输入的方法 public void keyIn(String msg) { out.getData(msg); } // 定义一个模拟打印的方法 public void print() { System.out.println(name + "开始打印..."); out.out(); } }
package lee; import org.crazyit.ioc.*; /** * Description: * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> * <br/>Copyright (C), 2001-2016, Yeeku.H.Lee * <br/>This program is protected by copyright laws. * <br/>Program Name: * <br/>Date: * @author Yeeku.H.Lee kongyeeku@163.com * @version 1.0 */ public class IoCTest { public static void main(String[] args) throws Exception { // 创建IoC容器 ApplicationContext ctx = new CrazyitXmlApplicationContext("beans.xml"); // 从IoC容器中取出computer Bean Computer c = (Computer)ctx.getBean("computer"); // 测试Computer对象 c.keyIn("轻量级Java EE企业应用实战"); c.keyIn("疯狂Java讲义"); c.print(); System.out.println(ctx.getBean("now")); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | package lee; /** * Description: * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> * <br/>Copyright (C), 2001-2016, Yeeku.H.Lee * <br/>This program is protected by copyright laws. * <br/>Program Name: * <br/>Date: * @author Yeeku.H.Lee kongyeeku@163.com * @version 1.0 */ public interface Output { // 接口里定义的属性只能是常量 int MAX_CACHE_LINE = 50 ; // 接口里定义的只能是public的抽象实例方法 void out(); void getData(String msg); } |
package lee; /** * Description: * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> * <br/>Copyright (C), 2001-2016, Yeeku.H.Lee * <br/>This program is protected by copyright laws. * <br/>Program Name: * <br/>Date: * @author Yeeku.H.Lee kongyeeku@163.com * @version 1.0 */ // 让Printer类实现Output public class Printer implements Output { private String[] printData = new String[MAX_CACHE_LINE]; // 用以记录当前需打印的作业数 private int dataNum = 0; public void out() { // 只要还有作业,继续打印 while(dataNum > 0) { System.out.println("打印机打印:" + printData[0]); // 把作业队列整体前移一位,并将剩下的作业数减1 System.arraycopy(printData , 1, printData, 0, --dataNum); } } public void getData(String msg) { if (dataNum >= MAX_CACHE_LINE) { System.out.println("输出队列已满,添加失败"); } else { // 把打印数据添加到队列里,已保存数据的数量加1。 printData[dataNum++] = msg; } } }
package org.crazyit.ioc; /** * Description: * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> * <br/>Copyright (C), 2001-2016, Yeeku.H.Lee * <br/>This program is protected by copyright laws. * <br/>Program Name: * <br/>Date: * @author Yeeku.H.Lee kongyeeku@163.com * @version 1.0 */ public interface ApplicationContext { // 获取指定Bean实例的方法 Object getBean(String name) throws Exception; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | package org.crazyit.ioc; import java.lang.reflect.*; import java.util.*; import java.io.*; import org.dom4j.*; import org.dom4j.io.*; /** * Description: * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> * <br/>Copyright (C), 2001-2016, Yeeku.H.Lee * <br/>This program is protected by copyright laws. * <br/>Program Name: * <br/>Date: * @author Yeeku.H.Lee kongyeeku@163.com * @version 1.0 */ public class CrazyitXmlApplicationContext implements ApplicationContext { // 保存容器中所有单例模式的Bean实例 private Map<String , Object> objPool = Collections.synchronizedMap( new HashMap<String , Object>()); // 保存配置文件对应的Document对象 private Document doc; // 保存配置文件里的根元素 private Element root; public CrazyitXmlApplicationContext(String filePath) throws Exception { SAXReader reader = new SAXReader(); doc = reader.read( new File(filePath)); root = doc.getRootElement(); initPool(); initProp(); } public Object getBean(String name) throws Exception { Object target = objPool.get(name); // 对于singleton Bean,容器已经初始化了所有Bean实例,直接返回即可 if (target.getClass() != String. class ) { return target; } else { String clazz = (String)target; // 对于prototype对象并未注入属性值 return Class.forName(clazz).newInstance(); } } // 初始化容器中所有singleton Bean private void initPool() throws Exception { // 遍历配置文件里的每个<bean.../>元素 for (Object obj : root.elements()) { Element beanEle = (Element)obj; // 取得<bean.../>元素的id属性 String beanId = beanEle.attributeValue( "id" ); // 取得<bean.../>元素的class属性 String beanClazz = beanEle.attributeValue( "class" ); // 取得<bean.../>元素的scope属性 String beanScope = beanEle.attributeValue( "scope" ); // 如果<bean.../>元素的scope属性不存在,或为singleton if (beanScope == null || beanScope.equals( "singleton" )) { // 以默认构造器创建Bean实例,并将其放入objPool中 objPool.put(beanId , Class.forName(beanClazz).newInstance()); } else { // 对于非singlton Bean,存放该Bean实现类的类名。 objPool.put(beanId , beanClazz); } } } // 初始化容器中singleton Bean的属性 private void initProp() throws Exception { // 遍历配置文件里的每个<bean.../>元素 for (Object obj : root.elements()) { Element beanEle = (Element)obj; // 取得<bean.../>元素的id属性 String beanId = beanEle.attributeValue( "id" ); // 取得<bean.../>元素的scope属性 String beanScope = beanEle.attributeValue( "scope" ); // 如果<bean.../>元素的scope属性不存在,或为singleton if (beanScope == null || beanScope.equals( "singleton" )) { // 取出objPool的指定的Bean实例 Object bean = objPool.get(beanId); // 遍历<bean.../>元素的每个<property.../>子元素 for (Object prop : beanEle.elements()) { Element propEle = (Element)prop; // 取得<property.../>元素的name属性 String propName = propEle.attributeValue( "name" ); // 取得<property.../>元素的value属性 String propValue = propEle.attributeValue( "value" ); // 取得<property.../>元素的ref属性 String propRef = propEle.attributeValue( "ref" ); // 将属性名的首字母大写 String propNameCamelize = propName.substring( 0 , 1 ) .toUpperCase() + propName.substring( 1 , propName.length()); // 如果<property.../>元素的value属性值存在 if (propValue != null && propValue.length() > 0 ) { // 获取设值注入所需的setter方法 Method setter = bean.getClass().getMethod( "set" + propNameCamelize , String. class ); // 执行setter注入 setter.invoke(bean , propValue); } if (propRef != null && propRef.length() > 0 ) { // 取得需要被依赖注入的Bean实例 Object target = objPool.get(propRef); //objPool池中不存在指定Bean实例 if (target == null ) { // 此处还应处理Singleton Bean依赖prototype Bean的情形 } // 定义设值注入所需的setter方法 Method setter = null ; // 遍历target对象所所实现的所有接口 for (Class superInterface : target.getClass().getInterfaces()) { try { // 获取设值注入所需的setter方法 setter = bean.getClass().getMethod( "set" + propNameCamelize , superInterface); // 如果成功取得该接口对应的方法,直接跳出循环 break ; } catch (NoSuchMethodException ex) { // 如果没有找到对应的setter方法,继续下次循环 continue ; } } // 如果setter方法依然为null, // 则直接取得target实现类对应的setter方法 if (setter == null ) { setter = bean.getClass().getMethod( "set" + propNameCamelize , target.getClass()); } // 执行setter注入 setter.invoke(bean , target); } } } } } } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步