反射机制的运用

           前边一篇博客写过相关反射机制的基础知识:java中的反射机制。写完这篇后有一条评论“反射反射程序员的快乐”,为什么说“快乐呢”,咱们看看反射的强大功能吧!这篇博客简单说一下反射机制的运用。

 

       反射机制,很多来说是Java中比较那学的东西,为什么?很多说是因为它比较抽象!说的也对,因为理解不了么,所以比较抽象。但是经过项目实践,框架的深究,感觉到反射有着强大的作用。是很多优秀框架的技术根源,是实现复用,达到解耦合的有利得手。因为反射不需要直到类,xml文件,等等的内容,只需要我们提前制定一种规则,那么我们就可以通过反射使我们的系统达到异常灵活的地步,使我们的开发有了那些提前写好可复用的代码——框架,这些可都是基于反射的强大作用。


         从现实生活中,我们找个反射的例子吧?什么类似Java中的反射机制呢???画家,它会画人像。来人出钱画个上学的学生,他马上画出来了;有来人出钱画个收小麦的农民,他也画出来了……     这就像我们的反射,过来什么类我们进行反射获取具体的类,就可以用它了,不用提前知道传过来的类的具体。而假如我们传统的new对象的画,必须知道传过来的对象,这样就很难达到多态的效果了。就像这个画家,如家就会画上学的儿童,那么那些想让他画农民的客户来了,就白跑了,这样显得画家的水平特别低了。转到我们的软件就是软件的功能特别单一了。


         那么通过反射在那些地方用的到呢?这里举两个例子:


         一,1,问题描述:一般在servlet或者anction类中,我们通过获取request中的数据,进行数据的封装,需要利用requestgetParameter一一取出数据来,然后再通过对象的set方法进行赋值,这样来看是非常麻烦呢?


       2,问题解决:通过反射我们可以不用知道request传过来的数据,只需要知道我们要封装的对象,就可以进行赋值,一次代码重复利用,达到了很好的复用效果。

              我们来看这个工具类:

	/**
	 * 工具类
	 * @author Administrator
	 */
	public class WebUtil {
	
		/**
		 * 通过反射机制将request对象中保存的数据设置到某个java对象中。
		 * @param request  请求对象,该对象中保存了用户从表单中提交的数据
		 * @param o java对象
		 */
		public static void makeRequestToObject(HttpServletRequest request,Object o){
			//获取类型
			Class c = o.getClass();
			
			//获取用户提交所有数据的name
			Enumeration<String> names = request.getParameterNames();
			//循环所有的name
			while(names.hasMoreElements()){
				//这里的name就是用户提交数据“=”左边的值
				String name = names.nextElement();
				//拼接方法名
				String methodName = "set" + name.toUpperCase().charAt(0) + name.substring(1);
				//获取方法
				try {
					Method setMethod = c.getMethod(methodName, String.class);
					//执行set方法,进行赋值
					setMethod.invoke(o, request.getParameter(name));
				} catch (Exception e) {
				} 
			}
		}
	}

        3,注意事项:当然,这里需要我们满足javabean规范,而且jsp页面的字段和bean里边的要一样等,就有一些规范了。



          二,1,问题描述:一般三层架构和MVC架构的层与层之间实现解耦合,而直接的分层加接口,耦合度还是很高的,如何使之间彼此不受影响呢?

        

        2,问题解决:利用反射:

 public static void createService(){
                   // 创建所有的Service对象
                 // 利用XPATH指定查询条件
		xpath = "//bean[@type='service']";

		// 获取所有的service类型的节点
		List<Element> serviceNodeList = doc.selectNodes(xpath);

		// 创建每一个service类型的对象,并存储到临时的内存空间中。
		for (Element serviceElement : serviceNodeList) {
			// 解析属性值
			String id = serviceElement.attributeValue("id");
			String className = serviceElement.attributeValue("class");
			// 反射创建对象
			Object serviceObject = Class.forName(className).newInstance();
			// 得到业务对象的类
			Class serviceClass = serviceObject.getClass();
			// 保存到临时的map集合中
			serviceObjectMap.put(id, serviceObject);

			// 这里需用将此service和dao的对象进行组合,利用本身的set方法
			List<Element> propertyElements = serviceElement.elements("property");
			for (Element proElement : propertyElements) {

				String fieldName = proElement.attributeValue("name");
				String refId = proElement.attributeValue("refId");
				// 获取关联对象
				Object daoObject = daoObjectMap.get(refId);
				// 获取对应的方法
				String methodName = "set"+ fieldName.substring(0, 1).toUpperCase()+ fieldName.substring(1);

				// 获取属性
				Field fieldObj = serviceClass.getDeclaredField(fieldName);
				Class fieldClazz = fieldObj.getType();

				// 获取属性的set方法
				Method methodOjbect = serviceClass.getDeclaredMethod(methodName,fieldClazz);

				// 利用反射调用set方法,组合对象关系
				methodOjbect.invoke(serviceObject, daoObject);

			}
		}
          }



       当然需要我们的xml文件来进行一些约束,有了一些规范:

	<?xml version="1.0" encoding="UTF-8"?>
	<beans>
	    <!-- 声明Dao层的对象 -->
		<bean id="userDao"  type="dao" class="com.ljh.system.dao.impl.UserDaoImpl"></bean>
		
		<!-- 声明Service对象 -->
		<bean id="userService"  type="service" class="com.ljh.system.service.impl.UserServiceImpl">
			<property name="userDao" refId="userDao"></property>
		</bean>
	
		<!-- 声明Action对象 -->
		<bean id="userAction" type="action" class="com.ljh.system.action.UserAction">
			<property name="userService" refId="userService"></property>
		</bean>
	</beans>

         这里是一个利用反射获取了service类,并且关联了dao类,感觉反射的作用是非常强大的。

         

          通过项目的实践,不仅加深了对反射机制的理解,更感觉到了它的无限魅力,有了反射,感觉很多问题都迎刃而解了!



评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值