相关设计模式

  • 适配器模式
  • 模板方法模式
  • 策略模式
  • 组合模式
  • 代理模式(使用Cglib的动态代理)

适配器模式

旧的类无法被删除和修改,在新的方法中对其进行方法的调用和前后进行操作

继承方式

  1. //被适配的类
  2. public class AdapterClass{
  3. public void handleMethod(){
  4. System.out.println("this is method to be handled")
  5. }
  6. }
  7. //适配器接口
  8. public interface Adapter{
  9. void handle();
  10. }
  11. //适配器实现类
  12. public class AdapterImpl extends AdapterClass implements Adapter{
  13. @Override
  14. public void handle(){
  15. super.handleMethod();
  16. }
  17. }
  18. //测试类
  19. public class Test{
  20. public static void main(Stirng[] args){
  21. Adapter adapter = new AdapterImpl();
  22. adapter.handle();
  23. }
  24. }

组合方式

  1. //被适配的类
  2. public class AdapterClass{
  3. public void handleMethod(){
  4. System.out.println("this is method to be handled")
  5. }
  6. }
  7. //适配器接口
  8. public interface Adapter{
  9. void handle();
  10. }
  11. //适配器实现类
  12. public class AdapterImpl implements Adapter{
  13. private AdapterClass adapterClass;
  14. public AdapterImpl(AdapterClass adapterClass){
  15. this.adapterClass = adapterClass;
  16. }
  17. @Override
  18. public void handle(){
  19. this.adapterClass.handleMethod();
  20. }
  21. }
  22. //测试类
  23. public class Test{
  24. public static void main(Stirng[] args){
  25. AdapterClass adapterClass = new AdapterClass();
  26. Adapter adapter = new AdapterImpl(adapterClass);
  27. adapter.handle();
  28. }
  29. }

模板方法模式

模板方法的构成

  1. 抽象的基类以及其中定义的若干个抽象方法和一个final方法
    • 定义为final是为了不让子类复写方法,改变实现逻辑
  2. 实现了抽象基类的具体的类,完成对抽象方法的实现
  1. //抽象基类
  2. public abstract class AbstractDatabaseExcecutor{
  3. abstract void openConnection();
  4. abstract String getResultSet();
  5. abstract void closeConnection();
  6. //为什么要定义为final是为了不让子类复写方法,改变实现逻辑
  7. public final void execute(){
  8. openConnection();
  9. getResultSet();
  10. closeConnection();
  11. }
  12. }
  13. //具体实现类1
  14. public class MysqlDatabaseExcutor extends AbstractDatabaseExcecuto{
  15. @Override
  16. void openConnection(){
  17. System.out.println("mysql open conneciton")
  18. }
  19. @Override
  20. String getResultSet(){
  21. System.out.println("mysql result set")
  22. }
  23. @Override
  24. void closeConnection(){
  25. System.out.println("mysql close connection")
  26. }
  27. }
  28. //具体实现类2
  29. public class OracleDatabaseExcutor extends AbstractDatabaseExcecuto{
  30. @Override
  31. void openConnection(){
  32. System.out.println("oracle open conneciton")
  33. }
  34. @Override
  35. String getResultSet(){
  36. System.out.println("oracle result set")
  37. }
  38. @Override
  39. void closeConnection(){
  40. System.out.println("oracle close connection")
  41. }
  42. }
  43. //测试类
  44. public class Test{
  45. public static void main(Stirng[] args){
  46. AbstractDatabaseExcecuto excutor = new MysqkDatabaseExcutor();
  47. excutor.execute();
  48. excutor = new OracleDatabaseExcutor();
  49. excutor.execute();
  50. }
  51. }

策略模式

有一个抽象的接口,这个接口只定义了一个模型,不提供具体的实现,不同实现类有不同的实现

  1. //抽象类
  2. public interface AbstractStrategy{
  3. int calc(int x, int y);
  4. }
  5. //加法实现类
  6. public class AddStrategy implements AbstractStrategy{
  7. @Override
  8. public int calc(int x, int y){
  9. return x + y;
  10. }
  11. }
  12. //减法实现类
  13. public class MinusStrategy implements AbstractStratgy{
  14. @Override
  15. public int calc(int x, int y){
  16. return x - y;
  17. }
  18. }
  19. //乘法实现类
  20. public class MultiStrategy implements AbstractStrategy{
  21. @Override
  22. public int calc(int x, int y){
  23. return x * y;
  24. }
  25. }
  26. //环境类
  27. public class Context{
  28. private AbstractStrategy abstractStrategy;
  29. public Context(AbstractStrategy abstractStrategy){
  30. this.abstractStrategy = abstractStrategy;
  31. }
  32. public void excecute(int x, int y){
  33. int calc = this.abstractStrategy.calc(x,y);
  34. System.out.println(calc);
  35. }
  36. }
  37. //测试类
  38. public class test{
  39. public static void main(Stirng[] args){
  40. Context context = new Context(new AddStrategy());
  41. context.excute(10,20);
  42. Context context = new Context(new MinusStrategy());
  43. context.excute(10,20);
  44. Context context = new Context(new MultiStrategy());
  45. context.excute(10,20);
  46. }
  47. }

组合模式

有一个篮子,篮子里承装任意多的对象,要把篮子里的任意对象遍历出来

  1. public abstract class Component{
  2. private String name;
  3. public String getName(){
  4. return name;
  5. }
  6. public Component(String name){
  7. this.name = name;
  8. }
  9. //protected
  10. protected abstract void dispaly();
  11. }
  1. public class Product extends Component{
  2. public Product(String name){
  3. super(name);
  4. }
  5. @Override
  6. protected void display(){
  7. System.out.println("the name of product is"+ this.getName());
  8. }
  9. }
  1. public class Box extends Componnet{
  2. private List<Component> productList = new ArrayList<>();
  3. public void addProduct(Component component){
  4. this.product.add(component);
  5. }
  6. public void removeProduct(Component component){
  7. this.product.remove(component);
  8. }
  9. public Box(String name){
  10. super(name);
  11. }
  12. @Override
  13. protected void display(){
  14. for(Component component : productList){
  15. component.display();
  16. }
  17. }
  18. }
  1. //手推车里放入了商品,打印手推车中的商品
  2. public class client{
  3. public static void main(String[] args){
  4. Box box = new Box("小推车");
  5. Component c1 = new Product("牙膏");
  6. Component c2 = new Product("肥皂");
  7. Component c3 = new Product("牙刷");
  8. box.addProcuct(c1);
  9. box.addProcuct(c2);
  10. box.addProcuct(c3);
  11. box.display();
  12. }
  13. }

代理模式(JDK动态代理、Cglib的动态代理)

代理某个类,在它的方法实现前后进行一些操作(增强) 包括动态代理和静态代理

动态代理:
c JDK动态代理

  1. public interface Target{
  2. void handle();
  3. }
  1. public class TargetImpl implements Target{
  2. @Override
  3. public void handle(){
  4. System.out.println("I can handle something");
  5. }
  6. }
  1. /**
  2. 代理类
  3. **/
  4. public class TargetHandler implements InvocatioinHandler{
  5. //被代理的类
  6. private Object target;
  7. public TargetHandler(Object target){
  8. this.target = target;
  9. }
  10. @Override
  11. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
  12. //方法前面操作
  13. Object invoke = method.invoke(target,args);
  14. //方法后面操作
  15. return invoke;
  16. }
  17. }
  1. public class Client{
  2. public static void main(String[] args){
  3. Target target = new TargetImpl();
  4. InvocatioinHandler handler = new TargetHandler(target);
  5. //代理对象 对象名{$Proxy0@502},非真实对象
  6. Target o = Proxy.newProxyInstance(target.getClass().getClassLoader(),
  7. target.getClass().getIntefaces(),handler)
  8. o.handle();
  9. }
  10. }

Cglib动态代理

  1. public class User{
  2. public void userMethod(){
  3. System.out.println("I am a user");
  4. }
  5. }
  1. //选择使用spring中的cgblib
  2. public class UserMethodIntercepter implements MethodIntercepter{
  3. @Override
  4. public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy){
  5. return methodProxy.invokeSuper(0,objects);
  6. }
  7. }
  1. public class Client{
  2. public static void main(String[] args){
  3. //spring的,proxy.Enhancer
  4. Enhancer enhancer = new Enhancer();
  5. //让其继承一个类
  6. enhancer.setSuperclass(User.class);
  7. enhancer.setCallbacek(new UserMethodIntercepter());
  8. User u = (User)enhancer.create();
  9. user.userMethod();
  10. }
  11. }

两种代理的区别

JDK要实现一个接口,CGLIB不要求实现一个接口,但是由于要生成一个子类,所以类不能被fianl修饰

反射相关API讲解

  1. public class Student{
  2. private void sayHello(String name){
  3. System.out.println("hello" + name);
  4. }
  5. }
  1. public class Client{
  2. public static void main(String[] args) throws NoSuchMethodException{
  3. Student student= new Student();
  4. Class<?> clazz = Student.class;
  5. Method method = clazz.getDeclareMehod("sayHello",String.calss);
  6. //设置允许
  7. method.setAccessibale(true);
  8. //参数数组
  9. String[] strings = new String[]{"zhangsan"};
  10. method.invoke(student,strings);
  11. }
  12. }
  13. //如果将整个main方法移入到student类中,那么无需设置axxessibale就可以访问,因为main本身就在Student类中

分析SpringMvc中重要的类和组件

基于HttpServlet的API的一层封装

  • FrameworkServlet
  • DispatcherServlet
  • HandlerInterceptor
  • HandlerInteceptorAdapter
  • HandlerMapping
  • HandlerMethod
  • HandlerAdapter
  • MethodParameter
  • HandlerMethodArgumentResolver
  • HandlerMethodArgumentResolverComposite
  • RequestResponseBodyMethodProcessor

FrameworkServlet

  1. //处理web请求的一般过程是继承HttpServlet然后实现其中的doPost(post请求)和doGet方法(get请求)
  2. public abstract class HttpServlet extends GenericServlet{
  3. ....
  4. }
  5. //查找实现了doGet方法的类,ctrl+T,找到了FrameworkServlet
  6. //它继承了HttpServlet实现了doGet方法,它在springframework.web.servlet包中,请求就正式转入了spring的控制

DispatcherServlet

  1. //也在org.springframework.web.servlet中,根据请求找到处理请求的组件(controller)
  2. //提供便捷的映射和异常处理的公共组件

HandlerInterceptor

拦截器顶层的实现接口,对请求的若干个阶段进行拦截

  1. //jdk1.8之后的default关键字,实现此接口可以不用实现所有的方法
  2. public interface HandlerInterceptor {
  3. //请求开始之前
  4. default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  5. return true;
  6. }
  7. //请求结束之后,画面渲染之前
  8. default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
  9. }
  10. //画面渲染之后(有的时候画面不存在,如modelAndView为空的情况)
  11. default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
  12. }
  13. }

HandlerInterceptorAdapter

此类的作用,如果直接实现HandlerInterceptor就要重写所有方法,实现HandlerInterceptorAdapter方法不需要重写所有方法,JDK1.8的default关键字已实现,作用变为了兼容一些老接口

  1. public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {
  2. @Override
  3. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
  4. throws Exception {
  5. return true;
  6. }
  7. @Override
  8. public void postHandle(
  9. HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
  10. throws Exception {
  11. }
  12. @Override
  13. public void afterCompletion(
  14. HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
  15. throws Exception {
  16. }
  17. @Override
  18. public void afterConcurrentHandlingStarted(
  19. HttpServletRequest request, HttpServletResponse response, Object handler)
  20. throws Exception {
  21. }
  22. }
  23. public interface AsyncHandlerInterceptor extends HandlerInterceptor {
  24. /**
  25. * Called instead of {@code postHandle} and {@code afterCompletion}, when
  26. * the a handler is being executed concurrently.
  27. * <p>Implementations may use the provided request and response but should
  28. * avoid modifying them in ways that would conflict with the concurrent
  29. * execution of the handler. A typical use of this method would be to
  30. * clean up thread-local variables.
  31. */
  32. void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler)
  33. throws Exception;
  34. }

HandlerMappping

处理请求到处理器的映射的作用,处理@RequestMapping等注解的方法/类与请求URL的映射 接口

  1. //MatchableHandlerMapping繼承了HandlerMappping接口
  2. public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping
  3. implements MatchableHandlerMapping, EmbeddedValueResolverAware {
  4. ....
  5. }

HandlerMethod

可以理解为RequestMappingHandlerMapping映射出的方法,即类似@RequestMapping注解的方法 方法的元信息

HandlerAdapter

适配器模式,为什么是适配器模式,这个adapter判断是通过继承controller方法进行的处理 还是通过注解的方式

  1. //在直接大量出现之前都是要实现该接口,重写该方法
  2. @FunctionalInterfa ce
  3. public interface Controller {
  4. @Nullable
  5. ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;
  6. }

MethodParameter

封装了注解了@RequstMapping的方法的请求参数,请求参数的注解

HandlerMethodArgumentResolver

对请求参数进行处理

  1. public interface HandlerMethodArgumentResolver {
  2. //判断传入的MethodParameter是否能够被当前的HandlerMethodArgumentResolver执行
  3. //eg:PathvariableMapMethodArgumentResolver
  4. boolean supportsParameter(MethodParameter parameter);
  5. //supportsParameter返回为true时调用该方法,同时将请求参数转到参数中
  6. @Nullable
  7. Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
  8. NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;
  9. }

HandlerMethodArgumentResolverComposite

使用了组合设计模式,组合了HandlerMethodArgumentResolver,封装了HandlerMethodArgumentResolver一系列的实现器,方便用来方便遍历解析器集合,可以理解为一个HandlerMethodArgumentResolver的容器

  1. public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgumentResolver {
  2. protected final Log logger = LogFactory.getLog(getClass());
  3. private final List<HandlerMethodArgumentResolver> argumentResolvers = new LinkedList<>();
  4. private final Map<MethodParameter, HandlerMethodArgumentResolver> argumentResolverCache =
  5. new ConcurrentHashMap<>(256);
  6. /**
  7. * Add the given {@link HandlerMethodArgumentResolver}.
  8. */
  9. public HandlerMethodArgumentResolverComposite addResolver(HandlerMethodArgumentResolver resolver) {
  10. this.argumentResolvers.add(resolver);
  11. return this;
  12. }
  13. /**
  14. * Add the given {@link HandlerMethodArgumentResolver}s.
  15. * @since 4.3
  16. */
  17. public HandlerMethodArgumentResolverComposite addResolvers(@Nullable HandlerMethodArgumentResolver... resolvers) {
  18. if (resolvers != null) {
  19. for (HandlerMethodArgumentResolver resolver : resolvers) {
  20. this.argumentResolvers.add(resolver);
  21. }
  22. }
  23. return this;
  24. }
  25. /**
  26. * Add the given {@link HandlerMethodArgumentResolver}s.
  27. */
  28. public HandlerMethodArgumentResolverComposite addResolvers(
  29. @Nullable List<? extends HandlerMethodArgumentResolver> resolvers) {
  30. if (resolvers != null) {
  31. for (HandlerMethodArgumentResolver resolver : resolvers) {
  32. this.argumentResolvers.add(resolver);
  33. }
  34. }
  35. return this;
  36. }
  37. /**
  38. * Return a read-only list with the contained resolvers, or an empty list.
  39. */
  40. public List<HandlerMethodArgumentResolver> getResolvers() {
  41. return Collections.unmodifiableList(this.argumentResolvers);
  42. }
  43. /**
  44. * Clear the list of configured resolvers.
  45. * @since 4.3
  46. */
  47. public void clear() {
  48. this.argumentResolvers.clear();
  49. }
  50. /**
  51. * Whether the given {@linkplain MethodParameter method parameter} is supported by any registered
  52. * {@link HandlerMethodArgumentResolver}.
  53. */
  54. @Override
  55. public boolean supportsParameter(MethodParameter parameter) {
  56. return (getArgumentResolver(parameter) != null);
  57. }
  58. /**
  59. * Iterate over registered {@link HandlerMethodArgumentResolver}s and invoke the one that supports it.
  60. * @throws IllegalStateException if no suitable {@link HandlerMethodArgumentResolver} is found.
  61. */
  62. @Override
  63. @Nullable
  64. public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
  65. NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
  66. HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
  67. if (resolver == null) {
  68. throw new IllegalArgumentException("Unknown parameter type [" + parameter.getParameterType().getName() + "]");
  69. }
  70. return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
  71. }
  72. /**
  73. * Find a registered {@link HandlerMethodArgumentResolver} that supports the given method parameter.
  74. */
  75. @Nullable
  76. private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
  77. HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);
  78. if (result == null) {
  79. for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) {
  80. if (logger.isTraceEnabled()) {
  81. logger.trace("Testing if argument resolver [" + methodArgumentResolver + "] supports [" +
  82. parameter.getGenericParameterType() + "]");
  83. }
  84. if (methodArgumentResolver.supportsParameter(parameter)) {
  85. result = methodArgumentResolver;
  86. this.argumentResolverCache.put(parameter, result);
  87. break;
  88. }
  89. }
  90. }
  91. return result;
  92. }
  93. }

RequestResponseBodyMethodProcessor

@RequestBody和@ResponseBody处理

  1. //最上层实现了HandlerMethodArgumentResolver,是用来处理@RequestBody类的请求
  2. //supportsReturnType和handleReturnValue是处理返回值的
  3. public class RequestResponseBodyMethodProcessor extends AbstractMessageConverterMethodProcessor {
  4. /**
  5. * Basic constructor with converters only. Suitable for resolving
  6. * {@code @RequestBody}. For handling {@code @ResponseBody} consider also
  7. * providing a {@code ContentNegotiationManager}.
  8. */
  9. public RequestResponseBodyMethodProcessor(List<HttpMessageConverter<?>> converters) {
  10. super(converters);
  11. }
  12. /**
  13. * Basic constructor with converters and {@code ContentNegotiationManager}.
  14. * Suitable for resolving {@code @RequestBody} and handling
  15. * {@code @ResponseBody} without {@code Request~} or
  16. * {@code ResponseBodyAdvice}.
  17. */
  18. public RequestResponseBodyMethodProcessor(List<HttpMessageConverter<?>> converters,
  19. @Nullable ContentNegotiationManager manager) {
  20. super(converters, manager);
  21. }
  22. /**
  23. * Complete constructor for resolving {@code @RequestBody} method arguments.
  24. * For handling {@code @ResponseBody} consider also providing a
  25. * {@code ContentNegotiationManager}.
  26. * @since 4.2
  27. */
  28. public RequestResponseBodyMethodProcessor(List<HttpMessageConverter<?>> converters,
  29. @Nullable List<Object> requestResponseBodyAdvice) {
  30. super(converters, null, requestResponseBodyAdvice);
  31. }
  32. /**
  33. * Complete constructor for resolving {@code @RequestBody} and handling
  34. * {@code @ResponseBody}.
  35. */
  36. public RequestResponseBodyMethodProcessor(List<HttpMessageConverter<?>> converters,
  37. @Nullable ContentNegotiationManager manager, @Nullable List<Object> requestResponseBodyAdvice) {
  38. super(converters, manager, requestResponseBodyAdvice);
  39. }
  40. @Override
  41. public boolean supportsParameter(MethodParameter parameter) {
  42. return parameter.hasParameterAnnotation(RequestBody.class);
  43. }
  44. @Override
  45. public boolean supportsReturnType(MethodParameter returnType) {
  46. return (AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) ||
  47. returnType.hasMethodAnnotation(ResponseBody.class));
  48. }
  49. /**
  50. * Throws MethodArgumentNotValidException if validation fails.
  51. * @throws HttpMessageNotReadableException if {@link RequestBody#required()}
  52. * is {@code true} and there is no body content or if there is no suitable
  53. * converter to read the content with.
  54. */
  55. @Override
  56. public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
  57. NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
  58. parameter = parameter.nestedIfOptional();
  59. Object arg = readWithMessageConverters(webRequest, parameter, parameter.getNestedGenericParameterType());
  60. String name = Conventions.getVariableNameForParameter(parameter);
  61. if (binderFactory != null) {
  62. WebDataBinder binder = binderFactory.createBinder(webRequest, arg, name);
  63. if (arg != null) {
  64. validateIfApplicable(binder, parameter);
  65. if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
  66. throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());
  67. }
  68. }
  69. if (mavContainer != null) {
  70. mavContainer.addAttribute(BindingResult.MODEL_KEY_PREFIX + name, binder.getBindingResult());
  71. }
  72. }
  73. return adaptArgumentIfNecessary(arg, parameter);
  74. }
  75. @Override
  76. protected <T> Object readWithMessageConverters(NativeWebRequest webRequest, MethodParameter parameter,
  77. Type paramType) throws IOException, HttpMediaTypeNotSupportedException, HttpMessageNotReadableException {
  78. HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
  79. Assert.state(servletRequest != null, "No HttpServletRequest");
  80. ServletServerHttpRequest inputMessage = new ServletServerHttpRequest(servletRequest);
  81. Object arg = readWithMessageConverters(inputMessage, parameter, paramType);
  82. if (arg == null && checkRequired(parameter)) {
  83. throw new HttpMessageNotReadableException("Required request body is missing: " +
  84. parameter.getExecutable().toGenericString());
  85. }
  86. return arg;
  87. }
  88. protected boolean checkRequired(MethodParameter parameter) {
  89. RequestBody requestBody = parameter.getParameterAnnotation(RequestBody.class);
  90. return (requestBody != null && requestBody.required() && !parameter.isOptional());
  91. }
  92. @Override
  93. public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
  94. ModelAndViewContainer mavContainer, NativeWebRequest webRequest)
  95. throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {
  96. mavContainer.setRequestHandled(true);
  97. ServletServerHttpRequest inputMessage = createInputMessage(webRequest);
  98. ServletServerHttpResponse outputMessage = createOutputMessage(webRequest);
  99. //写回数据,java对象-> Json对象 -> 返回客户端
  100. // Try even with null return value. ResponseBodyAdvice could get involved.
  101. writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);
  102. }
  103. }

分析SpringMVC运行流程

  1. //model
  2. @Data
  3. public class User{
  4. private String firstName;
  5. private String lastName;
  6. }
  7. @RestCotroller
  8. @RequestMapping(value ="/user",method = RequestMethod.GET)
  9. public class UserController{
  10. @GetMapping("/info/{firstName}/{lastName}")
  11. public User getUser(@PathVariable("firstName") String firstName,
  12. @PathVariable("lastName") String lastName){
  13. User user = new User(firstName,lastName);
  14. System.out.println(user);
  15. return user;
  16. }
  17. }
  • 如果把getUser的方法设置为private也是可以的,使用的springMvc的反射

源码分析

  1. User user = new User(firstName,lastName); 处打断点
  2. HttpServlet的继承类-> FrameworkServlet的doGet方法 -> processRequest(..)
  3. -> doService(..)抽象类使用了模板方法 -> 子类DispatcherServlet的doService(..)方法
  4. -> doDispatch(..)处理handlerMapping和handlerAdapter的方法

详解doDispatch(..)