将ApplicationListener自动装配为null

时间:2016-12-15 19:21:31

标签: java spring null javabeans

亲爱的StackOverflow专家。

我们正在解决当前冲刺中的有趣问题,我们对Spring工作流程的理解不允许我们找到解决方案。 所以我们请您分享下一个问题的想法:

我们需要从现在无法修改的库中导入类。 问题是我们需要导入的类具有实现“ApplicationListener”的类的Autowired依赖性。 我们不会在代码中使用这种依赖(它用在我们不会调用的方法中)。

我们尝试将所有未使用的依赖项设置为null。 但是当我们将这个类设置为null时,我们得到一个例外:

Caused by: java.lang.IllegalArgumentException: Delegate listener must not be null

显然,我们不希望在我们的应用程序中实例化ApplicationListener类。

为了重现我们的情况,我们创建了一个简单的单元测试:

应用程序配置:

@Configuration
public class TestApplicationConfiguration {
    @Bean
    public ApplicationListener<ContextRefreshedEvent> applicationListener() {
        return null;
    }
}

测试类:

@ContextConfiguration(classes = TestApplicationConfiguration.class)
public class ConfigurationManagerTests extends      AbstractTestNGSpringContextTests {
    @Autowired
    private ApplicationListener<ContextRefreshedEvent> applicationListener;

    @Test
    public void dummyTest() {
        Assert.assertNull(applicationListener);
    }
}

下面列出的例外的完整堆栈跟踪。

java.lang.IllegalStateException: Failed to load ApplicationContext

    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
    at org.springframework.test.context.testng.AbstractTestNGSpringContextTests.springTestContextPrepareTestInstance(AbstractTestNGSpringContextTests.java:149)
    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:483)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:86)
    at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:514)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:215)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:142)
    at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:178)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
    at org.testng.TestRunner.privateRun(TestRunner.java:782)
    at org.testng.TestRunner.run(TestRunner.java:632)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:366)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:361)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:319)
    at org.testng.SuiteRunner.run(SuiteRunner.java:268)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1244)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1169)
    at org.testng.TestNG.run(TestNG.java:1064)
    at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
    at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:124)
    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:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.IllegalArgumentException: Delegate listener must not be null
    at org.springframework.util.Assert.notNull(Assert.java:115)
    at org.springframework.context.event.GenericApplicationListenerAdapter.<init>(GenericApplicationListenerAdapter.java:48)
    at org.springframework.context.event.AbstractApplicationEventMulticaster.supportsEvent(AbstractApplicationEventMulticaster.java:280)
    at org.springframework.context.event.AbstractApplicationEventMulticaster.retrieveApplicationListeners(AbstractApplicationEventMulticaster.java:229)
    at org.springframework.context.event.AbstractApplicationEventMulticaster.getApplicationListeners(AbstractApplicationEventMulticaster.java:185)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:382)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:336)
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:877)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:544)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:128)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:108)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:251)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
... 33 more

感谢。

1 个答案:

答案 0 :(得分:0)

看起来Spring本身不允许该bean为null,那么为什么不创建一个不执行任何操作的虚拟bean呢?

@Bean
public ApplicationListener<ContextRefreshedEvent> applicationListener() {
  return new ApplicationListener<ContextRefreshedEvent>() {
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
      // Do nothing
    }   
  };
}