针对IntelliJIdea中没有为Kotlin@ConfigurationProperties类生成spring-configuration-metadata.json文件这个问题,本篇文章进行了详
针对IntelliJ Idea中没有为Kotlin @ConfigurationProperties类生成spring-configuration- metadata.json文件这个问题,本篇文章进行了详细的解答,同时本文还将给你拓展@Configuration+@ConfigurationProperties+@EnableConfigurationProperties、@Configuration配置和@ConfigurationProperties加载外部配置注解的使用。、c# – container.RegisterWebApiControllers(GlobalConfiguration.Configuration)导致InvalidOperationException、com.intellij.lang.ant.config.impl.configuration.BuildFilePropertiesPanel的实例源码等相关知识,希望可以帮助到你。
本文目录一览:- IntelliJ Idea中没有为Kotlin @ConfigurationProperties类生成spring-configuration- metadata.json文件
- @Configuration+@ConfigurationProperties+@EnableConfigurationProperties
- @Configuration配置和@ConfigurationProperties加载外部配置注解的使用。
- c# – container.RegisterWebApiControllers(GlobalConfiguration.Configuration)导致InvalidOperationException
- com.intellij.lang.ant.config.impl.configuration.BuildFilePropertiesPanel的实例源码
IntelliJ Idea中没有为Kotlin @ConfigurationProperties类生成spring-configuration- metadata.json文件
我正在尝试为基于Spring Boot的项目生成spring-configuration-metadata.json文件。如果我使用Java
@ConfigurationProperties 类,则会正确并自动生成:
@ConfigurationProperties("myprops")public class MyProps { private String hello; public String getHello() { return hello; } public void setHello(String hello) { this.hello = hello; }}
但是,如果我使用Kotlin类,则不会生成 spring-configuration-metadata.json 文件(我已经尝试了
gradle build 和Idea Rebuild Project )。
@ConfigurationProperties("myprops")class MyProps { var hello: String? = null}
AFAIK Kotlin使用构造函数,getter和setter生成相同的类,并且应充当常规Java Bean。
有什么想法为什么 spring-boot-configuration-processor 不适用于Kotlin类?
答案1
小编典典谢谢您指出正确的方向。所以解决方案是添加
dependencies { ... kapt "org.springframework.boot:spring-boot-configuration-processor" optional "org.springframework.boot:spring-boot-configuration-processor" ...}
生成 build.gradle 文件,在命令行中运行 gradle compileJava 并在IntelliJ Idea设置
Build,Execution,Deployment- > Compiler-> Annotation Processor-> Enable
annotation processing中打开注释处理。其余配置保持不变
另请注意,没有此行
optional "org.springframework.boot:spring-boot-configuration-processor"
IntelliJ Idea将抱怨
无法解析配置属性
您的 application.properties* 或 application.yml中的 消息 *
@Configuration+@ConfigurationProperties+@EnableConfigurationProperties
@Configuration+@ConfigurationProperties+@EnableConfigurationProperties

最佳设计方案(现在又改板了):
Bean上面直接设置@ConfigurationProperties
//需要依赖spring-boot-configuration-processor
@ConfigurationProperties(prefix = "stu")
public class Stu {
String name;
public Stu(String name) {
this.name = name;
}
public Stu() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Stu{" +
"name=''" + name + ''\'''' +
''}'';
}
}
方式一:configuration上面跟随@EnableConfigurationProperties【这种情况只有configuration里面一个Bean 】
@Configuration
@EnableConfigurationProperties
public class StuConfiguration {
@Bean
public Stu stu(){
return new Stu();
}
}
方式二:configuration上面跟随@EnableConfigurationProperties【这种情况只有configuration里面一个Bean 】
package com.example.demo11.configuration;
import com.example.demo11.entity.Stu;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
//@EnableConfigurationProperties(Stu.class),如果携带class参数则有用注册Bean的能力,
//因为实现了ImportBeanDefinitionRegistrar接口,Import三插之一
//这里的Bean名称非常有意思【类型名称+全包名】
@EnableConfigurationProperties(Stu.class)
public class StuConfiguration {
@Bean
public Stu stu2(){
return new Stu();
}
}
启动查看
@SpringBootApplication
public class Demo11Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Demo11Application.class, args);
Stu stu = context.getBean("stu-com.example.demo11.entity.Stu", Stu.class);
System.out.println(context.getBeansOfType(Stu.class).size());
System.out.println(stu.toString());
context.close();
}
}
@Configuration配置和@ConfigurationProperties加载外部配置注解的使用。
那么在Spring boot项目中,应用上下文又是如何找到那么多配置并加载初始化好的呢?
@SpringBootApplication
spring boot项目推荐大家在主类中标注@SpringBootApplication这个注解,我们来看看它的源码:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration //配置
@EnableAutoConfiguration //启用自动配置
//组件扫描
@ComponentScan(excludeFilters = @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class))
public @interface SpringBootApplication {
//需要排除的自动配置类
Class<?>[] exclude() default {};
//需要排除的自动配置类类名
String[] excludeName() default {};
//扫描包路径
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
//扫描包路径类
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
}
@EnableAutoConfiguration
我们发现一个配置开关注解,名字叫@EnableAutoConfiguration,看看它的源码:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
//是否启用自动配置的总开关名
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
//需要排除的自动配置类
Class<?>[] exclude() default {};
//需要排除的自动配置类类名
String[] excludeName() default {};
}
EnableAutoConfigurationImportSelector
我们看到有一个@Import导入了选择器EnableAutoConfigurationImportSelector.class,看看它的源码:
public class EnableAutoConfigurationImportSelector
implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware,
BeanFactoryAware, EnvironmentAware, Ordered {
...
c# – container.RegisterWebApiControllers(GlobalConfiguration.Configuration)导致InvalidOperationException
但是组合根类中的这一行:
container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
导致异常:
System.TypeInitializationException : The type initializer for 'MyProject.Api.Test.Integration.HttpClientFactory' threw an exception. ---- system.invalidOperationException : This method cannot be called during the application's pre-start initialization phase. Result StackTrace: at MyProject.Api.Test.Integration.HttpClientFactory.Create() at MyProject.Api.Test.Integration.Controllers.ProductControllerIntegrationTest.<GetProductBarcode_Should_Return_Status_BadRequest_When_Barcode_Is_Empty>d__0.MoveNext() in d:\Projects\My\MyProject.Api.Test.Integration\Controllers\ProductControllerIntegrationTest.cs:line 26 ----- Inner Stack Trace ----- at System.Web.Compilation.BuildManager.EnsuretopLevelFilesCompiled() at System.Web.Compilation.BuildManager.GetReferencedAssemblies() at System.Web.Http.WebHost.WebHostAssembliesResolver.System.Web.Http.dispatcher.IAssembliesResolver.GetAssemblies() at System.Web.Http.dispatcher.DefaultHttpControllerTypeResolver.GetControllerTypes(IAssembliesResolver assembliesResolver) at System.Web.Http.WebHost.WebHostHttpControllerTypeResolver.GetControllerTypes(IAssembliesResolver assembliesResolver) at SimpleInjector.SimpleInjectorWebApiExtensions.GetControllerTypesFromConfiguration(HttpConfiguration configuration) at SimpleInjector.SimpleInjectorWebApiExtensions.RegisterWebApiControllers(Container container,HttpConfiguration configuration) at MyProject.Api.ContainerConfig.RegisterTypes(Container container) in d:\Projects\My\MyProject.Api\App_Start\ContainerConfig.cs:line 128 at MyProject.Api.ContainerConfig.CreateWebApiContainer() in d:\Projects\My\MyProject.Api\App_Start\ContainerConfig.cs:line 63 at MyProject.Api.Test.Integration.HttpClientFactory..cctor() in d:\Projects\My\MyProject.Api.Test.Integration\HttpClientFactory.cs:line 17
评论后,一切正常,网络应用程序本身和测试.
所以问题是:
>例外的原因是什么?
>(这种方法真的需要吗?)
这是HttpClientFactory的代码(一个辅助类,用于创建具有适当头的HttpClient,例如api密钥或授权):
internal static class HttpClientFactory { private static readonly Container _container = ContainerConfig.CreateWebApiContainer(); public static HttpClient Create() { var client = new HttpClient { BaseAddress = GetUrl() }; //... return client; } }
解决方法
但是,System.Web.Compilation.BuildManager不能在ASP.NET管道的早期调用,也不能在ASP.NET的上下文之外调用.由于您正在进行测试,BuildManage将抛出您遇到的异常.
所以这里的解决方案(或’技巧’)将在单元测试时替换默认的IAssembliesResolver.我认为旋转变压器看起来像这样:
public class TestAssembliesResolver : IAssembliesResolver { public ICollection<Assembly> GetAssemblies() { return AppDomain.CurrentDomain.GetAssemblies(); } } [TestMethod] public void TestMethod1() { // Replace the original IAssembliesResolver. GlobalConfiguration.Configuration.Services.Replace(typeof(IAssembliesResolver),new TestAssembliesResolver()); var container = SimpleInjectorWebApiInitializer.BuildContainer(); container.Verify(); }
你不得不处理这个问题有点不幸,特别是因为Simple Injector的设计是可测试的.我们似乎忽略了这一点,将RegisterWebApiControllers扩展方法与Web API深深地集成在一起.我们必须退后一步,思考如何更轻松地验证单元测试中的Web API配置.
com.intellij.lang.ant.config.impl.configuration.BuildFilePropertiesPanel的实例源码
public void setBuildFileProperties() { final AntBuildFileBase buildFile = getCurrentBuildFile(); if (buildFile != null && BuildFilePropertiesPanel.editBuildFile(buildFile,myProject)) { myConfig.updateBuildFile(buildFile); myBuilder.queueUpdate(); myTree.repaint(); } }
public void setBuildFileProperties() { final AntBuildFileBase buildFile = getCurrentBuildFile(); if (buildFile != null && BuildFilePropertiesPanel.editBuildFile(buildFile,myProject)) { myConfig.updateBuildFile(buildFile); myBuilder.queueUpdate(); myTree.repaint(); } }
public void setBuildFileProperties() { final AntBuildFileBase buildFile = getCurrentBuildFile(); if (buildFile != null && BuildFilePropertiesPanel.editBuildFile(buildFile,myProject)) { myConfig.updateBuildFile(buildFile); myBuilder.queueUpdate(); myTree.repaint(); } }
今天关于IntelliJ Idea中没有为Kotlin @ConfigurationProperties类生成spring-configuration- metadata.json文件的分享就到这里,希望大家有所收获,若想了解更多关于@Configuration+@ConfigurationProperties+@EnableConfigurationProperties、@Configuration配置和@ConfigurationProperties加载外部配置注解的使用。、c# – container.RegisterWebApiControllers(GlobalConfiguration.Configuration)导致InvalidOperationException、com.intellij.lang.ant.config.impl.configuration.BuildFilePropertiesPanel的实例源码等相关知识,可以在本站进行查询。
本文标签: