吴裕雄--天生自然轻量级JAVA EE企业应用开发Struts2Sping4Hibernate整合开发学习笔记:企业应用开发的思考和策略_IoC

<?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"));
    }
}
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;
}
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);
					}
				}
			}
		}
	}
}

  

原文地址:https://www.cnblogs.com/tszr/p/12373162.html