zoukankan      html  css  js  c++  java
  • Spring BeanWrapper分析

    最近在读DispatcherServlet 源代码,看到父级类org.springframework.web.servlet.HttpServletBean中关于BeanWrapper的一段代码, 继续追看下去,发现

    BeanWrapper 是spring 底层核心的JavaBean包装接口, 默认实现类BeanWrapperImpl.所有bean的属性设置都是通过它来实现。

    [java] view plain copy
     
    1. @Override  
    2.     public final void init() throws ServletException {  
    3.         if (logger.isDebugEnabled()) {  
    4.             logger.debug("Initializing servlet '" + getServletName() + "'");  
    5.         }  
    6.   
    7.         // Set bean properties from init parameters.  
    8.         try {  
    9.             PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);  
    10.             BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);  
    11.             ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());  
    12.             bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));  
    13.             initBeanWrapper(bw);  
    14.             bw.setPropertyValues(pvs, true);  
    15.         }  
    16.         catch (BeansException ex) {  
    17.             logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);  
    18.             throw ex;  
    19.         }  
    20.   
    21.         // Let subclasses do whatever initialization they like.  
    22.         initServletBean();  
    23.   
    24.         if (logger.isDebugEnabled()) {  
    25.             logger.debug("Servlet '" + getServletName() + "' configured successfully");  
    26.         }  

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory类 自动注入工厂抽象类

    [java] view plain copy
     
    1. @Override  
    2.     public Object configureBean(Object existingBean, String beanName) throws BeansException {  
    3.         markBeanAsCreated(beanName);  
    4.         BeanDefinition mbd = getMergedBeanDefinition(beanName);  
    5.         RootBeanDefinition bd = null;  
    6.         if (mbd instanceof RootBeanDefinition) {  
    7.             RootBeanDefinition rbd = (RootBeanDefinition) mbd;  
    8.             bd = (rbd.isPrototype() ? rbd : rbd.cloneBeanDefinition());  
    9.         }  
    10.         if (!mbd.isPrototype()) {  
    11.             if (bd == null) {  
    12.                 bd = new RootBeanDefinition(mbd);  
    13.             }  
    14.             bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);  
    15.             bd.allowCaching = false;  
    16.         }  
    17.        <span style="color:#FF0000;"> BeanWrapper bw = new BeanWrapperImpl(existingBean);</span>  
    18.         initBeanWrapper(bw);  
    19.         populateBean(beanName, bd, bw);  
    20.         return initializeBean(beanName, existingBean, bd);  
    21.     }  

    BeanWrapperImpl 继承了属性编辑注册功能

    如何设置值 :

    [java] view plain copy
     
    1. @Override  
    2.     public void setPropertyValue(String propertyName, Object value) throws BeansException {  
    3.         BeanWrapperImpl nestedBw;  
    4.         try {  
    5.            //获取嵌套的属性, like map[my.key], 没有嵌套属性就返回自己  
    6.             nestedBw = getBeanWrapperForPropertyPath(propertyName);  
    7.         }  
    8.         catch (NotReadablePropertyException ex) {  
    9.             throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,  
    10.                     "Nested property in path '" + propertyName + "' does not exist", ex);  
    11.         }  
    12.         PropertyTokenHolder tokens = getPropertyNameTokens(getFinalPath(nestedBw, propertyName));  
    13.         nestedBw.setPropertyValue(tokens, new PropertyValue(propertyName, value));  
    14.     }  


    看下面具体方法的实现

    [java] view plain copy
     
    1. /** 
    2.      * Recursively navigate to return a BeanWrapper for the nested property path. 
    3.      * @param propertyPath property property path, which may be nested 
    4.      * @return a BeanWrapper for the target bean 
    5.      */  
    6.     protected BeanWrapperImpl getBeanWrapperForPropertyPath(String propertyPath) {  
    7.         int pos = PropertyAccessorUtils.getFirstNestedPropertySeparatorIndex(propertyPath);  
    8.         // Handle nested properties recursively.  
    9.         if (pos > -1) {  
    10.             String nestedProperty = propertyPath.substring(0, pos);  
    11.             String nestedPath = propertyPath.substring(pos + 1);  
    12.                         //递归获取最后一个属性  
    13.                         BeanWrapperImpl nestedBw = getNestedBeanWrapper(nestedProperty);  
    14.             return nestedBw.getBeanWrapperForPropertyPath(nestedPath);  
    15.         }  
    16.         else {  
    17.             return this;  
    18.         }  
    19.     }  



    自己实现了个小例子:

    [java] view plain copy
     
    1. public class HelloWorld {  
    2.       
    3.     private String msg = null;  
    4.     private Date date = null;  
    5.     public String getMsg() {  
    6.         return msg;  
    7.     }  
    8.     public void setMsg(String msg) {  
    9.         this.msg = msg;  
    10.     }  
    11.     public Date getDate() {  
    12.         return date;  
    13.     }  
    14.     public void setDate(Date date) {  
    15.         this.date = date;  
    16.     }  
    17.   
    18. }  
    19.   
    20. package com.sunkey.test;  
    21.   
    22. public class Pepole {  
    23.   
    24.     private String name;  
    25.       
    26.     private int sex;  
    27.       
    28.     private HelloWorld helloWorld;  
    29.   
    30.     public String getName() {  
    31.         return name;  
    32.     }  
    33.   
    34.     public void setName(String name) {  
    35.         this.name = name;  
    36.     }  
    37.   
    38.     public int getSex() {  
    39.         return sex;  
    40.     }  
    41.   
    42.     public void setSex(int sex) {  
    43.         this.sex = sex;  
    44.     }  
    45.   
    46.     public HelloWorld getHelloWorld() {  
    47.         return helloWorld;  
    48.     }  
    49.   
    50.     public void setHelloWorld(HelloWorld helloWorld) {  
    51.         this.helloWorld = helloWorld;  
    52.     }  
    53.       
    54. }  


    测试代码:

    [java] view plain copy
     
      1.  @Test  
      2.     public void testBeanWapper() throws InstantiationException, IllegalAccessException, ClassNotFoundException {  
      3.         Object obj = Class.forName("com.sunkey.test.HelloWorld").newInstance();  
      4.         BeanWrapper bw = new BeanWrapperImpl(obj);  
      5.         bw.setPropertyValue("msg", "HellowWorld");  
      6.         bw.setPropertyValue("date", new Date());  
      7.         System.out.println(bw.getPropertyValue("date") + " " + bw.getPropertyValue("msg"));  
      8.     }  
      9.   
      10.     @Test  
      11.     public void testNestedBeanWapper() throws InstantiationException, IllegalAccessException, ClassNotFoundException {  
      12.         Object obj = Class.forName("com.sunkey.test.HelloWorld").newInstance();  
      13.         BeanWrapper bw = new BeanWrapperImpl(obj);  
      14.         bw.setPropertyValue("msg", "HellowWorld");  
      15.         bw.setPropertyValue("date", new Date());  
      16.         Object objP = Class.forName("com.sunkey.test.Pepole").newInstance();  
      17.         BeanWrapper pbw = new BeanWrapperImpl(objP);  
      18.         pbw.setPropertyValue("name", "jack");  
      19.         pbw.setPropertyValue("helloWorld", obj);  
      20.         System.out.println(pbw.getPropertyValue("name") + " " + pbw.getPropertyValue("helloWorld.msg"));  
      21.         pbw.setPropertyValue("helloWorld.msg", "HellowWorld修改过");  
      22.         System.out.println(pbw.getPropertyValue("name") + " " + pbw.getPropertyValue("helloWorld.msg")); }  
  • 相关阅读:
    Angular项目中引入jQuery
    ERROR in Error: ***Module is not an NgModule
    angular-cli项目报Error encountered resolving symbol values statically. Function calls are not supported.错误的处理。
    在angular项目中使用bootstrap的tooltip插件时,报错Property 'tooltip' does no t exist on type 'JQuery<HTMLElement>的解决方法和过程
    微信小程序学习笔记(四)--框架-视图层
    js打印窗口内容并当窗口内容较长时自动分页
    微信小程序学习笔记(三)--框架-逻辑层
    微信小程序学习笔记(二)--框架-全局及页面配置
    微信小程序学习笔记(一)--创建微信小程序
    在ag-grid表格上实现类似Excel中的按下enter键自动跳转到下一行对应的输入框功能,Angular4开发
  • 原文地址:https://www.cnblogs.com/dogdogwang/p/7079749.html
Copyright © 2011-2022 走看看