applicationContextAware接口实现类拿不到applicationContext对象的错误查找

本地项目启动过程中报错如下:

07-Nov-2019 09:48:01.926 SEVERE [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.StandardContext.filterStart Exception starting filter ecFilter
 com.baosight.iplat4j.core.exception.PlatException: E_Spring_BeansException
	at com.baosight.iplat4j.core.spring.SpringApplicationContext.getBean(SpringApplicationContext.java:91)
	at com.baosight.iplat4j.ec.util.UrlFilter.<init>(UrlFilter.java:32)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at java.lang.Class.newInstance(Class.java:442)
	at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:119)
	at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:258)
	at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:105)
	at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4660)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5298)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725)
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
	at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1696)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
	at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
	at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
	at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:484)
	at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:433)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
	at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
	at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
	at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468)
	at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
	at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309)
	at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401)
	at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)
	at sun.rmi.transport.Transport$1.run(Transport.java:200)
	at sun.rmi.transport.Transport$1.run(Transport.java:197)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
	at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
	at com.baosight.iplat4j.core.spring.SpringApplicationContext.getBean(SpringApplicationContext.java:88)
	... 54 more

可以看到报了空指针错误,在SpringApplicationContext类中的getBean 方法中,代码如下:
在这里插入图片描述
getApplicationContext()方法返回null ,进入该方法:

public static ApplicationContext getApplicationContext() {
        if(CONTEXT != null) {
            return CONTEXT;
        } else {
            try {
                lock.lock();
                if(CONTEXT != null) {
                    ApplicationContext var0 = CONTEXT;
                    return var0;
                }

                System.out.println("[SpringApplicationContext] try init context...");
                new ClassPathXmlApplicationContext("classpath*:spring/framework/applicationContext.xml");
                new ClassPathXmlApplicationContext(fileNames);
                if(CONTEXT == null) {
                    throw new Exception("[SpringApplicationContext] applicationContext未被初始化");
                }

通过调试发现该方法的CONTEXT 属性为空,然后直接抛出了异常:application未被初始化。由于该类实现了applicationContextAware接口,因此在类初始化时applicationcontext 对象会赋给CONTEXT属性。

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        CONTEXT = applicationContext;
    }

进一步调试发现,该set方法未执行,该类的构造方法也未执行,因此猜想是spring初始化类时出现了问题。所以接着调试web.xml中配置的spring容器初始化监听器ContextLoaderListener:
public void contextInitialized(ServletContextEvent event) {
this.contextLoader = this.createContextLoader();
if(this.contextLoader == null) {
this.contextLoader = this;
}

    this.contextLoader.initWebApplicationContext(event.getServletContext());
}

直接看initWebApplicationContext方法
在这里插入图片描述
然后进入createWebApplicationContext 方法:
在这里插入图片描述
其中的refresh()方法描述了ApplicationContext的初始化过程,其中大部分操作都是执行Bean定义到BeanDefinition到Bean的过程。

public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var4) {
                this.destroyBeans();
                this.cancelRefresh(var4);
                throw var4;
            }

        }
    }

refresh 方法中的obtainFreshBeanFactory方法只要执行了xml配置的bean的定义搜集操作:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        this.refreshBeanFactory();
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if(this.logger.isDebugEnabled()) {
            this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
        }

        return beanFactory;
    }

再看其中的refreshBeanFactory方法:

protected final void refreshBeanFactory() throws BeansException {
        if(this.hasBeanFactory()) {
            this.destroyBeans();
            this.closeBeanFactory();
        }

        try {
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
            beanFactory.setSerializationId(this.getId());
            this.customizeBeanFactory(beanFactory);
            this.loadBeanDefinitions(beanFactory);
            Object var2 = this.beanFactoryMonitor;
            synchronized(this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        } catch (IOException var4) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var4);
        }
    }

可以看到其中的loadBeanDefinitions方法就是去加载xml配置的bean定义的过程:
顺着这个方法往下找,最终可以找到加载contextConfigLocation中配置的xml文件加载路径的方法:
在这里插入图片描述
由于项目中配置了bean定义xml文件在spring/ 路径下,而此处加载路径时 返回的resourcesUrls为空。所以没有初始化bean。
后来发现是由于 项目结构中的 artifacts配置有问题,编译输出的class文件没放到web-inf classes 文件夹下,导致找不到xml配置文件。
在这里插入图片描述
修改output layout 后重新编译问题就解决了

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值