









工作的时候突然想到一个问题,valid运行机制。为什么直接引入包就可以了,valid运行机制。为什么直接引入包就可以了??
启动程序的时候: classLoader.getResources("META-INF/spring.factories") ; //获取所有查看有这个spring.factories文件的引入的jar包 在spring-boot-autoconfigure包里面的配置文件配置了需要启动时调用方法org.springframework.boot.autoconfigure.BackgroundPreinitializer 在org.springframework.boot.autoconfigre.BackgroundPreinitializer类 performPreinitialization()当中配置当中 //初始化ByteBuffer、字符串时区、时区时间转Calendar、对象之间转换、失败对象转字符串、对象转参数等等... this.runSafely(new ConversionServiceInitializer()); //初始化校验模块(在这里...........) this.runSafely(new ValidationInitializer()); //初始化消息转换模块 (支持消息转换模型 javax.xml.bind.Binder 、 com.fasterxml.jackson.databind.ObjectMapper 、 com.fasterxml.jackson.dataformat.xml.XmlMapper 、 com.fasterxml.jackson.dataformat.smile.SmileFactory 、 com.google.gson.Gson、 javax.json.bind.Jsonb ) this.runSafely(new MessageConverterInitializer()); //初始化MBean模块 (涉及tomcat相关模块 StringManager 内置线程安全hashtable;javax.management.MBeanServer) JMX核心 this.runSafely(new MBeanFactoryInitializer()); this.runSafely(new JacksonInitializer()); //初始化字符集 UTF-8 this.runSafely(new CharsetInitializer()); //计数器-1 BackgroundPreinitializer.preinitializationComplete.countDown(); 会预先加载 javax.validation.Validation.java中调用的configure()方法(在validation-api的jar包中) configrure()内部会在Validation.java中的内部私有单例类调用run方法: 1.获取当前线程的上下文ClassLoader 2.根据ClassLoader获取缓存cachedContextClassLoaderProviderList 列表 3.如果缓存没有,则通过loadProviders()方法进行加载: //java公共方法,将实现了javax.validation.spi.ValidationProvider接口的加载到LazyIterator 对象当中 java.util.ServiceLoader.load( ValidationProvider.class, classloader ) 4.迭代里面找到实现了ValidationProvider接口的实例类 org.hibernate.validator.HibernateValidator 5.通过class.newInstance()进行实例化 6.这里可能会有实现多个ValidationProvider接口的实例类,但是在configrure()内部会在Validation.java 只会取第一个。 //自动加载就完成了..
请求调用接口是这样....... 1.启动的时候先找org.springframework.context.ApplicationContextInitializer 模块 2.在找org.springframework.context.ApplicationListener 模块 3.在找org.springframework.boot.autoconfigure.AutoConfigurationImportListener 模块 4.在找org.springframework.boot.autoconfigure.AutoConfigurationImportFilter 模块 5.在找org.springframework.boot.autoconfigure.EnableAutoConfiguration 模块 1.启动的时候在spring-boot-autoconfigure包里面的配置文件 org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext 调用finishBeanFactoryInitialization(beanFactory)方法 创建服务. org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletContext servletContext) org.springframework.boot.web.servlet.ServletContextInitializerBeans (添加servlet进去) 添加几种模式: ServletRegistrationBean、 FilterRegistrationBean、 DelegatingFilterProxyRegistrationBean、 ServletListenerRegistrationBean、 或者ServletContextInitializer实现了接口的自定义Bean 请求接口的时候:(内部socket连接),建立连接 1.通过org.apache.tomcat.util.net.NioEndpoint 调用org.apache.coyote.AbstractProtocol.process()方法 2.process()内部调用org.apache.coyote.http11.Http11Processor.service()方法, 3.在service()里面进入了适配器(org.apache.catalina.connector.CoyoteAdapter) 4.在service()语法块中,postParseRequest(req, request, res, response);方法内设置了request、response基础信息 5.并在之后的this.connector.getService().getContainer().getPipeline().getFirst().invoke(request, response); 实际上是到...org.apache.catalina.core.StandardEngineValve.invoke(Request request, Response response) 通过连接得到服务、得到容器、得到管道、取第一个管道,进行回调 6.进一步到 -> org.apache.catalina.valves.ErrorReportValve.invoke(Request request, Response response) (这里处理servlet异常抛出问题) 7.进一步到 -> org.apache.catalina.core.StandardHostValve.invoke(Request request, Response response) 8.进一步到 -> org.apache.catalina.authenticator.AuthenticatorBase.invoke(Request request, Response response) 9.进一步到 -> org.apache.catalina.core.StandardContextValve.invoke(Request request, Response response) 10.进一步到-> org.apache.catalina.core.StandardWrapperValve.invoke(Request request, Response response) 在 org.apache.catalina.core.StandardWrapper.allocate() 加载【servlet(DisPatchServlet)】 在 request中设置 :org.apache.catalina.core.DISPATCHER_TYPE 和org.apache.catalina.core.DISPATCHER_REQUEST_PATH 参数 通过 StandardWrapper wrapper = (StandardWrapper)this.getContainer(); 得到wrapper 10.1.进一步到-> org.apache.catalina.core.ApplicationFilterFactory.createFilterChain(ServletRequest request, Wrapper wrapper, Servlet servlet) 创建filterChain,并通过filterChain.setServlet(servlet) 将servlet 设置到filter里面 =============================== 通过 StandardContext context = (StandardContext)wrapper.getParent(); FilterMap[] filterMaps = context.findFilterMaps(); 得到filterMap对象包含: characterEncodingFilter、webMvcMetricsFilter、hiddenHttpMethodFilter、httpPutFormContentFilter、 requestContextFilter、 org.springframework.boot.actuate.web.trace.servlet.httpTraceFilter、Tomcat WebSocket (JSR356) Filter 这些Filter都继承了OncePerRequestFilter ================================
遍历filterMap 通过匹配Dispatch类型以及url或者servlet名称的 ,filterConfig = (ApplicationFilterConfig)context.findFilterConfig(filterMaps[i].getFilterName()); 得到filterConfig对象 并依次通过 filterChain.addFilter(filterConfig)加入到加入到filter列表中 11.通过返回的filterChain.doFilter(request.getRequest(), response.getResponse()) 进行filter处理 12.进入org.springframework.web.filter.doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) 处理filter 13.进入org.springframework.web.filter.OncePerRequestFilter.doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) 通过抽象函数this.doFilterInternal(httpRequest, httpResponse, filterChain);调用对应的Filter实例方法 13.进入 org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) 14....依次进入Filter 在httpTraceFilter->org.apache.tomcat.websocket.server.wsFilter之后。。进入servlet处理 15.org.springframework.web.servlet.doDispatch(HttpServletRequest request, HttpServletResponse response)进行分发 在方法内调用 mappedHandler.applyPreHandle(processedRequest, response) 获取拦截器列表 WebMvcConfig、ConversionServiceExposingInterceptor、ResourceUrlProviderExposingInterceptor 16.拦截器过后执行AbstractHandlerMethodAdapter.handler() org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handler(HttpServletRequest request, HttpServletResponse response, Object handler) 17.进入 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) 进入 invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) 方法 18.进入org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(webRequest, mavContainer, new Object[0]); org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) org.springframework.web.method.support.resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) org.springframework.web.servlet.mvc.method.annotation.resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) 执行了this.validateIfApplicable(binder, parameter); 会去找注解为@Validated 或者@Valid开头的注解校验(这里就可以自定义校验注解,只要是Valid开头的) 19.进入org.springframework.validation.DataBinder.validate(Object... validationHints) org.springframework.boot.autoconfigure.validation.ValidatorAdapter.validate(Object target, Errors errors, Object... validationHints) org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(@Nullable Object target, Errors errors, @Nullable Object... validationHints) org.hibernate.validator.internal.engine.ValidatorImpl.validate(T object, Class<?>... groups) (实现了接口implements Validator, ExecutableValidator) org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidationContext<T> validationContext, ValueContext<U, Object> valueContext, ValidationOrder validationOrder) org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidationContext<?> validationContext, ValueContext<?, Object> valueContext) org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidationContext<?> validationContext, ValueContext<U, Object> valueContext) org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForSingleDefaultGroupElement(ValidationContext<?> validationContext, ValueContext<U, Object> valueContext, Map<Class<?>, Class<?>> validatedInterfaces, Class<? super U> clazz, Set<MetaConstraint<?>> metaConstraints, Group defaultSequenceMember) 在这里while(true)遍历所有校验值.... org.hibernate.validator.internal.engine.ValidatorImpl.validateMetaConstraint(ValidationContext<?> validationContext, ValueContext<?, Object> valueContext, Object parent, MetaConstraint<?> metaConstraint) org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(ValidationContext<?> validationContext, ValueContext<?, Object> valueContext) org.hibernate.validator.internal.metadata.core.MetaConstraint.doValidateConstraint(ValidationContext<?> executionContext, ValueContext<?, ?> valueContext) org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ValidationContext<T> executionContext, ValueContext<?, ?> valueContext) org.hibernate.validator.internal.engine.constraintvalidation.SimpleConstraintTree.validateConstraints(ValidationContext<T> validationContext, ValueContext<?, ?> valueContext, Set<ConstraintViolation<T>> constraintViolations) ConstraintValidator<B, ?> validator = this.getInitializedConstraintValidator(validationContext, valueContext); (得到校验器) ConstraintValidatorContextImpl constraintValidatorContext = new ConstraintValidatorContextImpl(validationContext.getParameterNames(), validationContext.getClockProvider(), valueContext.getPropertyPath(), this.descriptor, validationContext.getConstraintValidatorPayload()); this.validateSingleConstraint(validationContext, valueContext, constraintValidatorContext, validator) 在方法validateSingleConstraint(ValidationContext<T> executionContext, ValueContext<?, ?> valueContext, ConstraintValidatorContextImpl constraintValidatorContext, ConstraintValidator<A, V> validator)里面 V validatedValue = valueContext.getCurrentValidatedValue(); 执行isValid = validator.isValid(validatedValue, constraintValidatorContext);进行校验
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。