工作的时候突然想到一个问题,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-8this.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(); 得到wrapper10.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、ResourceUrlProviderExposingInterceptor16.拦截器过后执行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);进行校验