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

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

反射机制是什么:

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

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

public interface PremiumCaculator {
    DecimalFormat format = new DecimalFormat("##0.00");
    Map map = new HashMap();
    public Map 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 map = new HashMap();
        try {
            map = (Map) 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) wac.getBean("cargoPaidService")).findOne(cQuery);

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

"cargoPaidService" class="cn.wltc.biz.insurance.service.CargoPaidService">

这样就解决问题了。网上可以查到很多从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】基于java反射机制调用自定义类导致service注入失败的经验浅谈_第1张图片

参考文献:
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/

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

你可能感兴趣的:(java)