栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java 利用反射调用方法时遇到的一个问题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java 利用反射调用方法时遇到的一个问题

反射(Reflection) 是Java 的特征之一,它允许运行中的Java 程序获取自身的信息,并且可以操作类或对象的内部属性。

一开始的时候,使用newInstance()的方式,写测试的时候是没有问题的,只简单的打印出一句话。
下面是我一开始的写法

Object obj = Class.forName(类的全限定名).newInstance();

Method m = obj.getClass().getDeclaredMethod(方法名,...参数的类(多个以逗号分开));

m.invoke(obj, ...参数(多个以逗号分开));

然后在真正使用的时候,一直会报空指针的错误,导致反射没法用,通过断点追踪的时候发现,确实是进入方法中了,但是其类中注册的Service一直为NULL。原因就是通过Class.forName(类的全限定名)newInstance()序列化了一个新的对象,且这个对象内的属性并没有自动注入。

问题找到了,就是需要在反射的时候,保证其对象的内部属性有值即可。知道了问题出在哪就好办了,通过网上寻找了一番,找到了可实现的办法。

首先需要建立一个类用于实现ApplicationContextAware这个接口,ApplicationContext是我们常用的IOC容器,而他的顶层接口便是BeanFactory


import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;


@Slf4j
@Component
public class SpringContextHolder implements ApplicationContextAware {

    private static ApplicationContext applicationContext = null;


    
    public static ApplicationContext getApplicationContext() {
        assertContextInjected();
        return applicationContext;
    }

    
    @SuppressWarnings("unchecked")
    public static  T getBean(String name) {
        log.debug("从SpringContextHolder中取出Bean:" + name);
        assertContextInjected();
        return (T) applicationContext.getBean(name);
    }

    
    public static  T getBean(Class requiredType) {
        assertContextInjected();
        return applicationContext.getBean(requiredType);
    }

    
    public static void clearHolder() {
        log.debug("清除SpringContextHolder中的ApplicationContext:"
                + applicationContext);
        applicationContext = null;
    }

    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        if (SpringContextHolder.applicationContext != null) {
            log.info("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext);
        }
        SpringContextHolder.applicationContext = applicationContext;
    }

    
    public void destroy() throws Exception {
        SpringContextHolder.clearHolder();
    }

    
    private static void assertContextInjected() {
        if(applicationContext == null) {
            throw new IllegalStateException("applicaitonContext属性未注入, 请增加类注解:@Component("类名")");
        }
    }
}

然后是将原先的反射调用方法换成下面的代码

Object obj = SpringContextHolder.getBean(类的全限定名);

Method m = obj.getClass().getDeclaredMethod(方法名,...参数的类(多个以逗号分开));

m.invoke(obj, ...参数(多个以逗号分开));

经过测试,确实可用

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/682938.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号