Java bean方法参数和返回的SpringBoot验证

Java bean方法参数和返回的SpringBoot验证,java,spring-boot,bean-validation,Java,Spring Boot,Bean Validation,我无法正确进行方法级验证。或者我不明白它是怎么工作的 我的申请课在下面。很简单。它包含MethodValidationPostProcessorbean定义。它还提供迎宾服务 @springboot应用程序 公共类应用程序实现CommandLineRunner{ 私人最终迎宾员; 公共应用程序(迎宾员迎宾员){ this.greeter=问候者; } 公共静态void main(字符串[]args){ 新的SpringApplicationBuilder().main(App.class).so

我无法正确进行方法级验证。或者我不明白它是怎么工作的

我的申请课在下面。很简单。它包含
MethodValidationPostProcessor
bean定义。它还提供迎宾服务

@springboot应用程序
公共类应用程序实现CommandLineRunner{
私人最终迎宾员;
公共应用程序(迎宾员迎宾员){
this.greeter=问候者;
}
公共静态void main(字符串[]args){
新的SpringApplicationBuilder().main(App.class).sources(App.class).web(false).run(args).close();
}
@豆子
public org.springframework.validation.beanvalidation.MethodValidationPostProcessor MethodValidationPostProcessor()方法{
返回新的MethodValidationPostProcessor();
}
@凌驾
公共无效运行(字符串…参数)引发异常{
最终输入=新输入();
输入。设置名称(“j”);
最终字符串messageFromInput=greeter.getMessageFromInput(输入);
最终字符串messageFromString=greeter.getMessageFromString(“j”);
}
}
下面是迎宾服务。在这里,我确实希望验证输入和输出

@服务
@验证
公务舱迎宾员{
字符串getMessageFromInput(@Valid@NotNull输入名称){
返回“[输入]问候!哦,强大”+姓名+!”;
}
String getMessageFromString(@Size(min=4)字符串名称){
return“[来自字符串]问候!哦,强大的”+名字+!”;
}
}
输入DTO也非常简单

公共类输入{
@空空如也
@尺寸(最小值=3)
私有字符串名称;
//接球手、二传手和投球手都被选中。
}

由于这两种情况下的名称directstring和DTO仅为一个字母,因此我希望此设置会引发异常。不幸的是,什么也没有发生,应用程序成功完成。它与控制器的方法一起工作。但是我希望它能够与任何bean的方法一起工作。

您正在将您的
Greeter
bean作为构造函数参数注入到用
@SpringBootApplication
注释的类中,该类是
@Configuration
类。为了满足这种依赖性,
Greeter
ApplicationContext
的启动过程中很早就创建了,因此会将其作为代理创建的候选对象删除

CommandLineRunner
逻辑移动到
@Bean
带注释的方法,而不是将其作为构造函数参数注入,只需将
Greeter
作为依赖项注入即可。这将延迟bean的创建,从而使其可用于代理

@Bean
public CommandLineRunner runner(Greeter greeter) {
    return new CommandLineRunner() {

        @Override
        public void run(String... args) throws Exception {
            final Input input = new Input();
            input.setName("j");
            final String messageFromInput = greeter.getMessageFromInput(input);

            final String messageFromString = greeter.getMessageFromString("j");
        }
    };
}

另一件事是,由于代理的性质,
Greeter
的方法应该是
public

您正在将您的
Greeter
bean作为构造函数参数注入到用
@SpringBootApplication
注释的类中,该类是一个
@Configuration
类。为了满足这种依赖性,
Greeter
ApplicationContext
的启动过程中很早就创建了,因此会将其作为代理创建的候选对象删除

CommandLineRunner
逻辑移动到
@Bean
带注释的方法,而不是将其作为构造函数参数注入,只需将
Greeter
作为依赖项注入即可。这将延迟bean的创建,从而使其可用于代理

@Bean
public CommandLineRunner runner(Greeter greeter) {
    return new CommandLineRunner() {

        @Override
        public void run(String... args) throws Exception {
            final Input input = new Input();
            input.setName("j");
            final String messageFromInput = greeter.getMessageFromInput(input);

            final String messageFromString = greeter.getMessageFromString("j");
        }
    };
}

另一件事是,由于代理的性质,
Greeter
的方法应该是
public

不要使用
Greeter
作为构造函数参数。我猜这会触发bean的早期创建,使它不再是代理创建的候选对象,因此不会应用验证。创建一个
@Bean
方法,该方法创建
CommandLineRunner
,并将
Greeter
作为方法参数插入。另外,将您的方法
公开
,因为AOP只对公开方法有效。您对早期bean创建的看法是正确的。当我将运行程序移动到带有
Greeter
作为参数的bean工厂方法时,它工作得很好。似乎Greeter的
public
方法访问是不相关的。现在,当你们提到它时,我记得日志文件中的信息说,迎宾员不是合格的代理候选人。现在我知道了其中的含义。不要使用
Greeter
作为构造函数参数。我猜这会触发bean的早期创建,使它不再是代理创建的候选对象,因此不会应用验证。创建一个
@Bean
方法,该方法创建
CommandLineRunner
,并将
Greeter
作为方法参数插入。另外,将您的方法
公开
,因为AOP只对公开方法有效。您对早期bean创建的看法是正确的。当我将运行程序移动到带有
Greeter
作为参数的bean工厂方法时,它工作得很好。似乎Greeter的
public
方法访问是不相关的。现在,当你们提到它时,我记得日志文件中的信息说,迎宾员不是合格的代理候选人。现在我知道这意味着什么了。