利用java反射机制 读取配置文件 实现动态类载入以及动态类型转换
作者:54dabang
在spring的学习过程之中,我们能够看出通过配置文件来动态管理bean对象的优点(松耦合 能够让零散部分组成一个总体,而这些总体并不在意之间彼此的细节,从而达到了真正的物理上的疏散耦合,而非逻辑,有了IOC之后。我们能够让SPRING充当各框架中的整合器。把技术框架进行完美的结合)。
Spring实现的一个重要的机制是通过反射(java.lang.reflect)读取配置文件,通过配置文件来动态生成配置文件里的类对象。Java动态载入类主要是为了不改变主程序代码。通过改动配置文件就能够操作不同的对象运行不同的功能。
因为java是强类型语言。本文依据一篇老外的博客。给出了一种能够实现动态类型转换的可行性方法和思路。
本文主要帮助你完毕一下学习目标:
(1)反射机制最基础的学习。
(2) 通过最基础的java正則表達式读取配置文件,获取须要的信息。
(3) 模拟spring的IOC机制,实现类的动态载入。
(4) 给出程序源代码。測试,总结
(5) 利用java反射机制来实现动态类型转换(待完毕)
一 java反射机制最基础的学习
(1)关于java反射机制最基础的学习能够參考博客
http://blog.csdn.net/xiaoxian8023/article/details/9206055,内容比較具体。可是这篇文章里查找方法时。仅仅能依据methodName进行查找,无法精确查找到重载的方法(依据參数查找)。
这里讲两种方式列出来:
A)仅仅通过方法的名字进行查找 并调用 參数:被调用对象的实例 方法名 方法调用所须要的參数
public Object invokeMethodGernaral(Object owner,String methodName,Object[]args)
{
//a.先获取对象所属的类
Class ownerClass=owner.getClass();
Method method=null;
Object result=null;
//b.获取须要调用的方法
for(Method m:ownerClass.getDeclaredMethods())
{
if(m.getName().equalsIgnoreCase(methodName))
{
method=m;
break;
}
}
try {
//c.调用该方法
result=method.invoke(owner, args);//调用方法
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
B)仅仅通过方法的名字和參数进行精确匹配查找 并调用 參数:被调用对象的实例 方法名 參数的类型 方法调用所须要的參数
<pre name="code" class="java">public Object invokeMethod(Object owner,String methodName,Class[]clz,Object[] args) throws Exception {
//a.得到对象所属类
Class ownerClass=owner.getClass();
//b.依据方法名称和參数名称 获取该类的某个方法
Method method=ownerClass.getMethod(methodName,clz);//第二个參数是通过类型来获取 有个缺点就是參数类型必需要填写
//c.运行某个对象的方法
Object result=method.invoke(owner,args); //必需要有类对象才干够调用
//d.输出结果信息
System.out.println("结果返回值:"+ result);
return result;
}
二 通过最基础的java正則表達式读取配置文件,获取须要的信息。
从配置文件中读取信息,主要是用到IO流的操作,比較简单。为方便大家理解,我这里将其简化为一个字符串,然后利用正則表達式从中提取信息。
关于正則表達式的具体学习,能够參考我的博客:
http://blog.csdn.net/leixingbang1989/article/details/26486927
比如要匹配一下类型的字符串:
<metahttp-equiv="Content-Type"content="text/html; charset=UTF-8">
当中标红的部分为想要获取的数据。注意这里要获取的数据长度不固定,而且可能为unicode
Gb2312等其它编码类型,在这里我们所希望获取的是其编码方式。
这里给出一段最简单的代码:
public static String parse (String s)
{
Pattern pattern =Pattern.compile("charset=(.+?)\"");
//通配符中也要增加转移字符 (.+?)代表要查找的内容
Matcher matcher=pattern.matcher(s);
while(matcher.find())
{
System.out.println(matcher.group(1));
}
return s;
}
三 模拟spring的IOC机制。读取配置文件,实现类的动态载入
Spring的一个配置文件格式例如以下:
<beans>
<bean id="u" class="com.bjsxt.dao.impl.UserDAOImpl" >
</bean>
<bean id="userService" class="com.bjsxt.service.UserService" >
<property name="userDAO" bean="u"/>
</bean>
</beans>
我们能够用Pattern pattern =Pattern.compile("<beans>(.+?
)</beans>");来获取bean对象配置信息。然后再次利用正則表達式获取每一个bean信息。
在这里 我自己定义了一个配置文件信息,放到字符串中。
其配置格式为: 属性名称:值,
String Configure="Class:com.bjsxt.service.school,Method:getStudentInfo,args:Tom,argsType:java.lang.String";//格式固定 能够用正則表達式提取
String []split={":",","};//格式为 name:value, 所以分隔符为 : ,
parseData p=new parseData(Configure);//实现方式为正則表達式提取须要的字符串
//(1) 获取类名 方法名 參数 參数类型信息
String className= p.getInfo("Class", split);
String MethodName=p.getInfo("Method", split);
String arg=p.getInfo("args", split);
Object []args={arg};
String argsType=p.getInfo("argsType", split);
四给出程序源代码,測试,总结
package com.bjsxt.service; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; public class DynamicInvocation {
public static void main(String[] a) throws Exception {
String Configure="Class:com.bjsxt.service.school,Method:getStudentInfo,args:Tom,argsType:java.lang.String";//格式固定 能够用正則表達式提取
String []split={":",","};//格式为 name:value, 所以分隔符为 : ,
parseData p=new parseData(Configure);//实现方式为正則表達式提取需要的字符串
//(1) 获取类名 方法名 參数 參数类型信息
String className= p.getInfo("Class", split);
String MethodName=p.getInfo("Method", split);
String arg=p.getInfo("args", split);
Object []args={arg};
String argsType=p.getInfo("argsType", split);
//(2) 创建未知对象实例
Object s=Class.forName(className).newInstance();// 注意我们眼下创建的对象并不知道其类型
//(3)方法调用
//3.1仅通过方法名查找查找方法并调用 缺点:有可能有方法是重载的
DynamicInvocation inv=new DynamicInvocation();
inv.invokeMethodGernaral(s, MethodName, args);
//3.2通过方法名 和參数 查找方法并调用
Class cls=Class.forName(argsType);
System.out.println(cls.getName());
Class []clz={cls};
inv.invokeMethod(s, MethodName, clz, args);
//(4)动态强制类型转换
Class intClass=Class.forName("java.lang.Integer");
System.out.println(Integer.class); }
public Object invokeMethodGernaral(Object owner,String methodName,Object[]args)//仅仅通过方法的名字进行查找 并调用
{
//a.先获取对象所属的类
Class ownerClass=owner.getClass();
Method method=null;
Object result=null;
//b.获取需要调用的方法
for(Method m:ownerClass.getDeclaredMethods())
{
if(m.getName().equalsIgnoreCase(methodName))
{
method=m;
break;
}
}
try {
//c.调用该方法
result=method.invoke(owner, args);//调用方法
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
public Object invokeMethod(Object owner,String methodName,Class[]clz,Object[] args) throws Exception {
//a.得到对象所属类
Class ownerClass=owner.getClass();
//b.依据方法名称和參数名称 获取该类的某个方法
Method method=ownerClass.getMethod(methodName,clz);//第二个參数是通过类型来获取 有个缺点就是參数类型必需要填写
//c.运行某个对象的方法
Object result=method.invoke(owner,args); //必需要有类对象才干够调用
//d.输出结果信息
System.out.println("结果返回值:"+ result);
return result;
}
}
package com.bjsxt.service; import java.util.regex.Matcher;
import java.util.regex.Pattern; public class parseData {
private String strSource;//数据源
public parseData(String s)
{
this.strSource=s;
}
public String getInfo(String name,String []split)//名称。值,分隔符
{
String str=name+split[0]+"(.+? )"+split[1];
//System.out.println(str);
Pattern pattern =Pattern.compile(str);//匹配的模式
Matcher matcher=pattern.matcher(this.strSource);
String value="";
boolean isFind=false;
if(matcher.find())
{
value=matcher.group(1);
}else//可能是最后一个字符
{
pattern=Pattern.compile(name+split[0]+"(.+? )"+"$");//$ 表示为限定结尾
matcher=pattern.matcher(this.strSource);
if(matcher.find())
{
value=matcher.group(1);
} }
return value;
} }
五 利用java反射机制来实现动态类型转换(待完毕)
主要实现思想来自于老外的一篇博客:
http://prajith-javatechnical.blogspot.in/2014/09/casting-java-object-dynamically-using.html
因为今天老师给我安排了任务,我将在未来有时间的情况下。将博客翻译成中文并解析。
利用java反射机制 读取配置文件 实现动态类载入以及动态类型转换的更多相关文章
- 利用JAVA反射机制设计通用的DAO
利用JAVA反射机制设计一个通用的DAO 反射机制 反射机制指的是程序在运行时能够获取自身的信息.在java中,只要给定类的名字, 那么就可以通过反射机制来获得类的所有信息. 反射机制创建类对象 ...
- 利用Java反射机制对实体类的常用操作工具类ObjectUtil
代码: ObjectUtil类: import java.lang.reflect.Field; import java.math.BigDecimal; import java.text.Simpl ...
- 利用Java反射机制将Bean转成Map
import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang ...
- 利用java反射机制实现读取excel表格中的数据
如果直接把excel表格中的数据导入数据库,首先应该将excel中的数据读取出来. 为了实现代码重用,所以使用了Object,而最终的结果是要获取一个list如List<User>.Lis ...
- 不使用BeanUtils,利用Java反射机制:表单数据自动封装到JavaBean
在百度搜“java反射 将表单数据自动封装到javabean ”,第一页显示的都是一样的代码,都是利用导入第三方jar包<commons-beanutils>和<commons-lo ...
- 利用java反射机制编写solr通用的java客户端
一.前言 通过上一篇的讲解,我们知道了dynamicFiled字段,它是动态的,不需要显示的声明.而且一些常用的基本类型solr已经默认给我们创建好了. 例如:*_i,*_is,等. 如果我们要使用动 ...
- 利用Java反射机制优化简单工厂设计模式
之前项目有个需求,审批流程的时候要根据配置发送信息:发送短信.发送邮件.当时看到这个就想到要用工厂模式,为什么要用工厂模式呢?用工厂模式进行大型项目的开发,可以很好的进行项目并行开发.就是一个程序员和 ...
- 利用JAVA反射机制将JSON数据转换成JAVA对象
net.sf.json.JSONObject为我们提供了toBean方法用来转换为JAVA对象, 功能更为强大, 这里借鉴采用JDK的反射机制, 作为简单的辅助工具使用, 有些数据类型需要进行转 ...
- 利用java反射机制实现List>转化为List
BEGIN; 最近在用hibernate做项目,由于后续的业务功能比较多,然后框架原设计没有使用到一对多.一对一等特性,(艹TA妹)没办法,只能用原生sql语句获得需要的结果集.但是返回过来的是一个L ...
随机推荐
- poj 3181 Dollar Dayz (整数划分问题---递归+DP)
题目:http://poj.org/problem?id=3181 思路:将整数N划分为一系列正整数之和,最大不超过K.称为整数N的K划分. 递归:直接看代码: 动态规划:dp[i][j]:=将整数i ...
- Shell防DDOS攻击原理
#!/bin/sh #date:2015-12-13 #filename:fang-DOS.sh #version:v1.0 while true do #awk '{print $1}' ...
- Linux命令初步了解
知识点: 1.虚拟控制台: 在系统启动时直接进入字符工作方式后,系统提供了多个(默认为6个)虚拟控制台.每个虚拟控制台可以相互独立使用,互不影响. 可以使用Alt+F1~Alt+F6进行多个虚拟控制台 ...
- .net程序开发人员必看的变量的命名规则
(1)类名.属性名.方法名采用Pascal命名,如 class User { } interface IEditable { } bool ValidateInput() public int Age ...
- (转)SQL NEWID()随机函数
从A表随机取2条记录,用SELECT TOP 10 * FROM ywle order by newid()order by 一般是根据某一字段排序,newid()的返回值 是uniqueidenti ...
- (转)SQL中的ISNULL函数介绍
SQL中有多种多样的函数,下面将为您介绍SQL中的ISNULL函数,包括其语法.注释.返回类型等,供您参考,希望对您学习SQL能够有所帮助. ISNULL 使用指定的替换值替换 NULL. 语法ISN ...
- Sherpa | Complete Navigation System 介绍与教材
这里的夏尔巴人在iPad上使用的一种新的视频. 正如其名称所暗示的,夏尔巴人是所有您的导航需求的整体解决方案. 夏尔巴人带来了每个接口的三个主要的导航元素结合在一起 - 导航栏,侧边栏和页脚粘. 每一 ...
- DNN Module - Responsive Html Tabs 3 介绍
Responsive Html Tabs 模块可以运行于DNN7及以上版本,支持响应式.用户界面较为友好,可以插入自定义的HTML. Demo This is a user-friendly, ful ...
- spring-security 登陆认证之初次探究
首先,希望还对 spring-security框架完全不懂的新手 下载下Git源码. 引入到项目中.这个短文就是边看源码边聊的.也会启动下项目验证自己的推想. 一.登陆认证的登陆配置项 <for ...
- .net抓取网页数据
1.想通过代码获得某个页面的数据,首先根据右键查看页面源代码,通过分析.再通过下面代码,修改,一步步查找出所需内容,存入数据库. //根据Url地址得到网页的html源码 private string ...