基于java反射机制调用自定义类导致service注入失败的经验浅谈

来源:互联网 发布:网络交换机多少钱 编辑:程序博客网 时间:2024/06/05 20:18

使用场景:最近在做一个保费计算的方法,涉及到不同险种的计算,根据三方传来的request请求进行相应的保费计算。最开始用的方法是switch case形式,根据对方传来的id逐个判断属于哪种险种,然后就进入相应的方法体。这是一种算是比较low的写法,反正大学那会儿没少用。后来在同事的指导下,换了个高大上的写法。下面就来说说看。。。

反射机制是什么:

反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

五种险种,都有一个共同的方法就是计算caculate,所以就建立了一个公用的接口,再建立5个类来实现这个接口。
接口如下

public interface PremiumCaculator {    DecimalFormat format = new DecimalFormat("##0.00");    Map<String, String> map = new HashMap<String, String>();    public Map<String, String> caculate(String bizInfo) throws Exception;}

五个实现类就不贴出来了。下面进入正题吧。
这个是我要执行的主类:

//保费计算    @RequestMapping("/baoxianCaculate")    @ResponseBody    public Object baoxianCaculate(HttpServletRequest request) throws IOException,PremiumCaculateException{         String bizInfo = request.getParameter("bizInfo");               String serviceName = "cn.wltc.web.controller.insurance.premium.ZhonganWlzrxQynd";        Class cls = Class.forName(serviceName);        Method m = cls.getDeclaredMethod("caculate",String.class);        Map<String, String> map = new HashMap<String, String>();        try {            map = (Map<String, String>) m.invoke(cls.newInstance(),bizInfo);            map.put("productNo", productNo);        } catch (Exception e) {            String msg = ((InvocationTargetException) e).getTargetException().getMessage();            return new JsonResp(JsonResp.RESULT_FAIL,msg, null);        }        return new JsonResp(JsonResp.RESULT_SUCCESS,null, map);    }

cn.wltc.web.controller.insurance.premium.ZhonganWlzrxQynd 这个路径下的类中 我需要注入一个service来实现我的功能,但是此时执行时会出现service为空指针的情况。
我的解决方案:

WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext(); Class<?>  cls = wac.getBean("wlLiaPaidAService").getClass(); CargoPaid cPaid = ((BaseService<CargoPaid, Integer>) wac.getBean("cargoPaidService")).findOne(cQuery);

说的通俗一点,由于反射机制使得spring容器失效,没能及时加载进来,这个时候就需要手动从spring中getBean。此时还需要配置一下xml文件:

<bean id="cargoPaidService" class="cn.wltc.biz.insurance.service.CargoPaidService"></bean>

这样就解决问题了。网上可以查到很多从spring容器中获取bean的方法,可以选择适合的来解决眼前的问题。
还有一个小问题就是,JAVA反射如何捕获自定义的异常

if (jsonBiz.get("sumInsured")==null) {    throw new PremiumCaculateException("该物流责任险(整车保)无保额信息,请确认信息无误");}

这个异常是写在实现类里面的,就是java反射需要调用的那个类,自己自定义了一个异常。想要输出异常我的实现方法是:

try {    //要捕获异常的方法} catch (Exception e) {    String msg = ((InvocationTargetException) e).getTargetException().getMessage();    return new JsonResp(JsonResp.RESULT_FAIL,msg, null);}

注意这句话((InvocationTargetException) e).getTargetException().getMessage();
反射的地方的代码,还是会对你的自定义异常再一次封装成反射调用失败的异常。 所以如果要得到自己自定义的异常必须要用通过ex.getTargetException()来得到。

我的文件目录:
这里写图片描述

参考文献:
Java反射机制详解:http://baike.xsoftlab.net/view/209.html#3_5
spring反射机制:http://www.cnblogs.com/forerver-elf/p/4724199.html
获取Spring容器中的Bean:http://www.bbsmax.com/A/1O5E8aKnJ7/

我也是刚刚入行一年多一点,刚刚接触反射机制,也在学习中,不对的地方可以帮忙点出,或者提出更多的东西一起学习。

0 0
原创粉丝点击