这是Spring + Jackson + joda time的后续问题:如何指定序列化/反序列化格式?.
在写最终版代码的时候,第一次写成这样:(只显示相关部分)
@Configuration
public class WebMvcConfiguration
{
@Bean
public WebMvcConfigurerAdapter apiWebMvcConfiguration()
{
return new ApiWebMvcConfiguration();
}
public class ApiWebMvcConfiguration extends WebMvcConfigurerAdapter
{
public ApiWebMvcConfiguration()
{
log.debug("### ApiWebMvcConfiguration");
}
@Bean
public UserInterceptor userInterceptor()
{
return new UserInterceptor(false);
}
@Override
public void addInterceptors(InterceptorRegistry registry)
{
log.debug("### addInterceptors");
registry.addInterceptor(userInterceptor())
.addPathPatterns("/api/user/**");
}
}
private static final Log log =
LogFactory.getLog(WebMvcConfiguration.class);
}
没有 @EnableWebMvc,因为使用了 Spring Boot 的默认 @EnableWebMvc 类。
请注意,userInterceptor bean 在 WebMvcConfigurerAdapter 类中,它也是一个 bean。
当我运行应用程序时,出现以下错误:(
我的类的类路径名被我自己替换为'...')
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name '...WebMvcConfiguration$ApiWebMvcConfiguration': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [...WebMvcConfiguration$ApiWebMvcConfiguration]: No default constructor found; nested exception is java.lang.NoSuchMethodException: ...WebMvcConfiguration$ApiWebMvcConfiguration.<init>()
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1076)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1021)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:124)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:609)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
at ...Application.main(Application.java:17)
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [...WebMvcConfiguration$ApiWebMvcConfiguration]: No default constructor found; nested exception is java.lang.NoSuchMethodException: ...WebMvcConfiguration$ApiWebMvcConfiguration.<init>()
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:85)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1069)
... 14 more
Caused by: java.lang.NoSuchMethodException: ...WebMvcConfiguration$ApiWebMvcConfiguration.<init>()
at java.lang.Class.getConstructor0(Class.java:2810)
at java.lang.Class.getDeclaredConstructor(Class.java:2053)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80)
... 15 more
然后我将 ApiWebMvcConfiguration 类更改为静态内部类。
应用程序“正常”启动,但 ApiWebMvcConfiguration 类被实例化了两次。也就是说,“### ApiWebMvcConfiguration”被打印了两次。因此,“### addInterceptors”被打印了两次。
然后,当 UserIntercepter 的代码运行时,它因为 null @Autowired JdbcTemplate 而失败。也就是说,@Autowired 不适用于该对象。(JdbcTemplate 在其他对象中成功@Autowired)
于是,我把代码改成了最终版本,如Spring + Jackson + joda time:如何指定序列化/反序列化格式?,即UserIntercepter bean被拉出ApiWebMvcConfiguration,问题就没有了。
这是正确的行为吗?
@Bean 不应该嵌套吗?