Today, Leadr put forward the requirement that the code efficiency of reading and parsing XML files in the original project of the company was too low, so we considered switching XML to data encapsulation format and reading mode to improve efficiency. It occurred to me that Spring’s dependency injection of beans is to read XML files. You can try to scratch spring’s source code to implement a lightweight solution.

Refactor the XML file to match the Spring XML file format

The reconstructed XML file format is as follows:

<? xml version="1.0" encoding="UTF-8"? > <beans> <bean name="iaminformation" class="com.whf.readxml.model.IamConfig">
        <property name="iamUrl" value="HTTP: 192.168.7.154:8080" />
        <property name="token" value="abcdefg" />
        <property name="iamName" value="CLP Branch" />
        <property name="sourceNumber" value="4" />
        <property name="timeSpan" value="12" />
    </bean>

    <bean name="plugin" class="com.whf.readxml.model.PluginAttributes">
        <property name="name" value="ADTest1" />
        <property name="pluginType" value="AdPlugin" />
        <property name="code" value="100001" />
        <property name="url" value="Ldap: / / 192.168.7.241:389" />
        <property name="adminPsw" value="1qaz2wsx2017" />
        <property name="adminName" value="QUARKDATA\administrator" />
        <property name="adDn" value="OU=test,DC=quarkdata,DC=com" />
        <property name="securityAuthentication" value="simple" />

        <property name="staffFieldMatch">
            <bean name="staffFieldMatch" class="com.whf.readxml.model.StaffFieldMatch">
                <property name="idField" value="objectGUID" />
                <property name="userNameField" value="sAMAccountName" />
                <property name="firstNameField" value="givenName" />
                <property name="lastNameField" value="sn" />
                <property name="displayNameField" value="displayName" />
                <property name="phoneNumberField" value="" />
                <property name="telField" value="homePhone" />
                <property name="emailField" value="email" />
            </bean>
        </property>

        <property name="orgFieldMatch">
            <bean name="orgFieldMatch" class="com.whf.readxml.model.OrgFieldMatch">
                <property name="idField" value="objectGUID" />
                <property name="nameField" value="name" />
                <property name="displayNameField" value="ou" />
            </bean>
        </property>

        <property name="groupFieldMatch">
            <bean name="groupFieldMatch" class="com.whf.readxml.model.GroupFieldMatch">
                <property name="idFied" value="objectGUID" />
                <property name="nameField" value="sAMAccountName" />
                <property name="displayNameField" value="displayName" />
                <property name="decriptionField" value="info" />
            </bean>
        </property>
    </bean>

    <bean name="plugin" class="com.whf.readxml.model.PluginAttributes">
        <property name="name" value="LDAPTest1" />
        <property name="pluginType" value="LdapPlugin" />
        <property name="code" value="100002" />
        <property name="url" value="Ldap: / / 192.168.7.245 /" />
        <property name="adminPsw" value="test123456" />
        <property name="adminName" value="cn=admin,dc=thundersoft,dc=com" />
        <property name="adDn" value="dc=thundersoft,dc=com" />
        <property name="securityAuthentication" value="simple" />
        <property name="staffFieldMatch">
            <bean name="staffFieldMatch" class="com.whf.readxml.model.StaffFieldMatch">
                <property name="idField" value="gidNumber" />
                <property name="userNameField" value="uid" />
                <property name="firstNameField" value="givenName" />
                <property name="lastNameField" value="sn" />
                <property name="displayNameField" value="displayName" />
                <property name="phoneNumberField" value="telephoneNumber" />
                <property name="telField" value="tel" />
                <property name="emailField" value="email" />
            </bean>
        </property>

        <property name="orgFieldMatch">
            <bean name="orgFieldMatch" class="com.whf.readxml.model.OrgFieldMatch">
                <property name="idField" value="dn" />
                <property name="nameField" value="ou" />
                <property name="displayNameField" value="orgDisplayName" />
            </bean>
        </property>

        <property name="groupFieldMatch">
            <bean name="groupFieldMatch" class="com.whf.readxml.model.GroupFieldMatch">
                <property name="idFied" value="dn" />
                <property name="nameField" value="cn" />
                <property name="displayNameField" value="groupDisplayName" />
                <property name="decriptionField" value="description" />
            </bean>
        </property>
    </bean>
</beans>Copy the code

Does this look familiar to you, just like the Spring configuration file?

Spring reads the source of the XML file

Because spring is too large, the method of reading SPRING XML is divided into n multiple methods according to different tags, the main ability of the building is not here to show off, However, Spring loads beans from configuration files into bean factories in the same theoretical way as reading XML files below.

No more nonsense, on the code:

* @author WHF * @date Aug 23, 2017 */ public class XMLBeanFactory { private String xmlName; private SAXReader reader; private Document document; */ public XMLBeanFactory(String xmlName) {// In the constructor try {this.xmlName = xmlName;  reader = new SAXReader(); document = reader.read(this.getClass().getClassLoader().getResourceAsStream(xmlName)); } catch (DocumentException e) { e.printStackTrace(); } /** * get the same type of bean. * @paramtypeClass type of bean. * @returnThrows Exception Exception. */ public <T> List<T> getBeansOfType(Class<T>type) throws Exception {
        List<T> objects = new ArrayList<>();
        try {
            Element root = document.getRootElement();
            List<Element> beans = root.elements();
            if (beans.size() > 0) {
                for (Element bean : beans) {
                    if (bean.attributeValue("class").equals(type.getName())) {
                        T object = null;
                        String clazz = bean.attributeValue("class"); Class beanClass = class.forname (clazz); object = (T) beanClass.newInstance(); List<Element> propertys = bean.elements();if (propertys.size() > 0) {
                            for (Element property : propertys) {
                                String key = property.attributeValue("name");
                                Field field = beanClass.getDeclaredField(key);
                                field.setAccessible(true); List<Element> childBean = property.elements(); // If there is an embedded bean under propertyif (childBean.size() > 0) {
                                    Object childObject = getBean(key, property);
                                    field.set(object, childObject);
                                } else{/* * This attribute value is a string. I'm going to do int separately,floatClassCastException */ String Value = property.attributeValue("value"); // The type needs to be determinedif (field.getType().getName().equals("int"Int x = integer.parseInt (value); // int x = integer.parseint (value); field.set(object, x);continue;
                                    }
                                    if (field.getType().getName().equals("float") {// floatfloaty = Float.parseFloat(value); field.set(object, y); // Note that double is acceptablefloattypecontinue; } field.set(object, value); }} objects.add(object); } } } } catch (Exception e) { e.printStackTrace(); }returnobjects; } /** * get the bean embedded in the property. * @param name ID or bean name * @param root nodereturn* @throws Exception Exception. */ Public Object getBean(String name, Element root) throws Exception { Object object = null; List<Element> beans = root.elements();if (beans.size() > 0) {
            for (Element bean : beans) {
                if (bean.attributeValue("name").equals(name)) {// If the bean name is the same, start creating the object String clazz = bean.attributeValue("class"); Class beanClass = class.forname (clazz); object = beanClass.newInstance(); List<Element> propertys = bean.elements();if (propertys.size() > 0) {
                        for (Element property : propertys) {
                            String key = property.attributeValue("name");
                            Field field = beanClass.getDeclaredField(key);
                            field.setAccessible(true); List<Element> childBean = property.elements(); // If there is an embedded bean under propertyif (childBean.size() > 0) {
                                field.set(object, getBean(key, property));
                            }

                            if (property.attribute("ref")! = null) {/* * This property's value is an object. */ String refid = property.attributeValue() */ String refid = property.attributeValue()"ref");
                                field.set(object, getBean(refid));
                            } else{/* * This attribute value is a string. I'm going to do int separately,floatClassCastException */ String Value = property.attributeValue("value"); Field. Set (object, value); // Handle the String type}}}}}}returnobject; }}Copy the code

The following code is used to retrieve beans of the same type from an XML file. Specific how to achieve, look at the code, notes written very clear.

File reading efficiency is increased by more than 120 times

After the completion of the code, compared with the previous code to read XML, the efficiency increased by 120.

To summarize

Danniu said to see the source code of the open source framework, how the harvest will be, but for most of the pseudo code farmers to scratch the source code is always confused, unknowing. However, when we really need, the implementation of open source code has become a huge treasure, with our purpose to scratch the source code, sometimes there will be twice the result with half the effort. Building Lord pro test effective, although the source is good, do not drink oh.

Source: blog.csdn.net/github_3637…