Java反射机制在开发工作中的一个应用-通过反射调用一个类中的非黑名单方法

前言

体能状态先于精神状态,习惯先于决心,聚焦先于喜好

需求

博主近期处理一个需求,将使用 Spring Quartz 跑批的定时任务改造为对外暴露的接口.

需求分析

这个需求的出发点是这样的,这个系统是一个很古老的系统,使用Spring Quartz,而公司后期已经有专门的定时任务组件了,只要将相应接口暴露出来就行.
由于 Quartz 的定时频率是在代码里写死的,而这个定时任务是用于生成好几家保险公司的对账文件,有时候系统出现问题,生成历史对账文件就变成了一个很棘手的问题,所以很有必要将之改造.

常规开发

常规开发的话,只需要将每个保险公司生成对账文件的方法(因为不同保险公司要求不一样,所以每一家保险公司都需要单独写一个方法)暴露为接口就行了.
比如,有20家保险公司,就暴露20个方法

多想一步:防止系统意外,提供一个集中调用的方法

用上面的小标题,常规开发是可以解决问题的,但是这样一来,一单系统出现了异常,需要手动触发指定日期的对账方法时,就要重复触发n次,所以这里应该提供一个集中触发的方法,在平时,每个保险公司的方法都是单独触发的,在意外情况下则可以单独调用这个总方法,总方法内部自己去调用其他20多个方法.

技术实现

对于20多个方法这里不做赘述,主要是这个总方法怎么写?

常规写法:在总方法中一一罗列调用子方法

将需要被调用的子方法进行罗列,并依次调用
为了防止一个方法出现异常导致后面的任务无法执行,所以每次调用都需要try catch 包围起来
可以想象,这样这个类有多长?

/**
* 	总方法调用子方法
*/
public class Demo(){
	public boolean allWorkers(){
		try{
			worker1();
		}catch(Exception e){
			//todo 错误处理
		}
		try{
			worker2();
		}catch(Exception e){
			//todo 错误处理
		}
		try{
			worker3();
		}catch(Exception e){
			//todo 错误处理
		}
		//其余略...
	}
}
多想一步:用反射来解决这个问题

上面的方法虽然可以解决问题,但是使得代码过于冗长,反正这个总方法就是把所有本类中的其他方法调用一下,那么直接使用反射机制获取所有的子方法循环调用即可

回忆反射机制

好记忆不如烂笔头,博主翻了一下之前写的关于反射的系列博文 https://blog.csdn.net/bestcxx/column/info/19241
直接看 (二)利用反射机制实例化类,获取和修改变量,获取和调用方法和构造方法 即可
我们需要参考的demo代码如下

Class<?> obj=Demo4.class;	
try {
	//获得方法
	Method method=obj.getDeclaredMethod("method2", String.class);
	
	//获取一个对象
	Object demo4= obj.newInstance();
	
	//允许反射方法调用 private 修饰的方法
	method.setAccessible(true);
	
	//反射 调用 方法,并传入参数
	method.invoke(demo4, "name2");
	
实际应用

由于实际项目中使用了 Spring 对 bean 进行管理,所以我们没有必要
Object demo4= obj.newInstance(); 这行代码
但是 method.invoke(demo4, “name2”); 中需要 demo4 是一个对象
在实际操作中,我一共采用了三种操作

  • 使用Spring @Autowired 自己注入自己;可行
  • 使用 ClassA a=new ClassA(); 可行
  • 直接使用this;可行

由于我的方法就是本方法调用本类的其余方法,所以,这里可以使用 this 调用反射方法是最好的方式

@Override
	public boolean allWokers(String yyyyMMdd) {
		
		logger.info("调用总方法 allWokers,yyyyMMdd="+yyyyMMdd);
		Class<?> demoClass=DemoFacade.class;
		//获取所有本类的公共方法
		Method[] methods=demoClass.getMethods();
		//遍历调用
		for(Method m:methods) {
			//与本方法同名的方法不调用
			if(!m.getName().equals("allWokers")) {
				try {
					m.invoke(this, yyyyMMdd);
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return false;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值