JAVA反射机制的简单应用(1)

本文介绍通过Java反射机制实现依赖注入的过程。具体演示了如何使用XML配置文件定义对象及其依赖关系,并通过BeanFactory类根据这些配置信息创建并关联Employee和Address对象。

JAVA反射机制的简单应用(1)

Spring中的IOC(控制翻转,又叫依赖注入)

先来看一个例子,A对象关联B对象,学过UML的都知道这是指A类中有一个B类的成员变量,那么我们在创建A对象时,可以用构造函数或者set方法将B类对象与A类对象关联在一起,这种A与B之间的关系需要我们在代码中表现出来,我们也可以把这些代码叫做 硬编码

那么依赖注入所要解决的问题便是将这两个对象之间的关联关系的设置过程交给一个配置文件去维护,配置文件中指明了我们要将哪个B对象注入到A对象当中,这里涉及到工厂模式,需要有一个工厂对象,这个对象读取配置文件,根据配置文件的设置来完成B对象的创建以及属性注入的功能,这样当改变两个对象间的关系时,只需要改变配置文件即可,这样就摆脱了依赖注入的局限。

下面实现一个简单的反射应用,从xml文件中读取配置信息,利用反射创建 Employee,Address 实例并将Address实例与Employee实例关联在一起,这一切全是由BeanFactory类完成的,我们不会在类中写上 以下硬编码

Employee e = new Employee();

Address addr = new Address();

...

e.setAddr(addr);

而是由BeanFactory类根据配置文件bean.xml中的配置信息自动实现和上述代码同样的功能,很多框架底层也是这样来实现的。

 

<?xml version="1.0" ?>
<beans>
<bean id="b01" class="edu.zhutong.reflection.application.Employee">
	<property name="name" value="zhutong"></property>
	<property name="age" value="24"></property>
	<property name="salary" value="7000.53"></property>
	<property name="addr" ref="b03"></property>
</bean>
<bean id="b02" class="edu.zhutong.reflection.application.Address">
	<property name="street" value="PingLeYuan"></property>
	<property name="no" value="No100"></property>
</bean>
<bean id="b03" class="edu.zhutong.reflection.application.Address">
	<property name="street" value="SongYuDongLi"></property>
	<property name="no" value="No23"></property>
</bean>
</beans>
 
public class Employee {
	private String name;
	private int age;
	private double salary;
	private Address addr;
	public Employee() {
		super();
	}
	public Address getAddr() {
		return addr;
	}
	public void setAddr(Address addr) {
		this.addr = addr;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public double getSalary() {
		return salary;
	}
	public void setSalary(double salary) {
		this.salary = salary;
	}
	public String toString(){
		return "Employee name="+name+" age="+age+" salary="+salary+" address="+addr;
	}
}
 
public class Address {
	private String street;
	private String no;
	public Address() {
		super();
	}
	public String getNo() {
		return no;
	}
	public void setNo(String no) {
		this.no = no;
	}
	public String getStreet() {
		return street;
	}
	public void setStreet(String street) {
		this.street = street;
	}
	public String toString(){
		return street+"  No"+no;
	}
}
 
public class BeanFactory {
	private Map<String,Element> map=new HashMap<String,Element>();
	//在构造方法中载入xml文件,将Element对象以id为key放入Map
	public BeanFactory(){
		try {
			DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
			DocumentBuilder db=dbf.newDocumentBuilder();
			Document doc=db.parse("beans.xml");
			NodeList nl=doc.getElementsByTagName("bean");
			for(int i=0;i<nl.getLength();i++){
				Element e=(Element)nl.item(i);
				String id=e.getAttribute("id");
				map.put(id, e);
			}
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public Object getBean(String id){
		try {
			//分析class属性 利用反射创建对象
			Element ele=map.get(id);
			String className=ele.getAttribute("class");
			Class c=Class.forName(className);
			Object result=c.newInstance();
			
			//逐个为result对象设置属性
			NodeList children=ele.getElementsByTagName("property");
			for(int i=0;i<children.getLength();i++){
				Element child=(Element)children.item(i);
				//获得属性名
				String fieldName=child.getAttribute("name");
				String value=child.getAttribute("value");
				String ref=child.getAttribute("ref");
				
				//获得属性类型
				Field f=c.getDeclaredField(fieldName);
				Class type=f.getType();
				//获得设置属性的方法名
				char[] cs=fieldName.toCharArray();
				cs[0]-=32;
				String methodName=new String(cs);
				methodName="set"+methodName;
				//利用反射,调用setXXX方法,设置属性值
				Method m=c.getDeclaredMethod(methodName, type);
				Object o=value;
				if (value.equals("")){
					o=getBean(ref);
				}
				else{
					String valueClassName=type.getSimpleName();
					if (valueClassName.equals("int")) o=new Integer(value);
					if (valueClassName.equals("double")) o=new Double(value);
				}
				m.invoke(result, o);
			}
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} 
		
		
	}
}
 
name= zhutong age= 24 height= 7000.53  street= SongYuDongLi no=No23
 

 

Delphi 12.3 作为一款面向 Windows 平台的集成开发环境,由 Embarcadero Technologies 负责其持续演进。该环境以 Object Pascal 语言为核心,并依托 Visual Component Library(VCL)框架,广泛应用于各类桌面软件、数据库系统及企业级解决方案的开发。在此生态中,Excel4Delphi 作为一个重要的社区开源项目,致力于搭建 Delphi 与 Microsoft Excel 之间的高效桥梁,使开发者能够在自研程序中直接调用 Excel 的文档处理、工作表管理、单元格操作及宏执行等功能。 该项目以库文件与组件包的形式提供,开发者将其集成至 Delphi 工程后,即可通过封装良好的接口实现对 Excel 的编程控制。具体功能涵盖创建与编辑工作簿、格式化单元格、批量导入导出数据,乃至执行内置公式与宏指令等高级操作。这一机制显著降低了在财务分析、报表自动生成、数据整理等场景中实现 Excel 功能集成的技术门槛,使开发者无需深入掌握 COM 编程或 Excel 底层 API 即可完成复杂任务。 使用 Excel4Delphi 需具备基础的 Delphi 编程知识,并对 Excel 对象模型有一定理解。实践中需注意不同 Excel 版本间的兼容性,并严格遵循项目文档进行环境配置与依赖部署。此外,操作过程中应遵循文件访问的最佳实践,例如确保目标文件未被独占锁定,并实施完整的异常处理机制,以防数据损毁或程序意外中断。 该项目的持续维护依赖于 Delphi 开发者社区的集体贡献,通过定期更新以适配新版开发环境与 Office 套件,并修复已发现的问题。对于需要深度融合 Excel 功能的 Delphi 应用而言,Excel4Delphi 提供了经过充分测试的可靠代码基础,使开发团队能更专注于业务逻辑与用户体验的优化,从而提升整体开发效率与软件质量。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值