• 反射结合xml简单的模拟spring创建bean


    框架最底层其实就是通过反射实现的,就像spring,当你配置各种各样的bean时都是以配置文件的形式配置的,你需要用到哪些bean就配哪些,spring容器就会根据你的需求去动态加载,这儿写一个简单的例子模拟一下:

    1.加深对反射的理解,

    2.了解一下框架的实现的原理

    3.通过dom4j对xml的解析

    两个简单的类:

    User:

    public class User {
    	
    	private String userName;
    	private  String userPwd;
    	private String userAge;
    	
    	public String getUserAge() {
    		return userAge;
    	}
    
    	public void setUserAge(String userAge) {
    		this.userAge = userAge;
    	}
    
    	public String getUserName() {
    		return userName;
    	}
    
    	public void setUserName(String userName) {
    		this.userName = userName;
    	}
    	
    	public String getUserPwd() {
    		return userPwd;
    	}
    
    	public void setUserPwd(String userPwd) {
    		this.userPwd = userPwd;
    	}
    }
    

      Student类:

    public class Student {
    	
    	private String stuName;
    	private String stuNo;
    	
    	public String getStuName() {
    		return stuName;
    	}
    	public void setStuName(String stuName) {
    		this.stuName = stuName;
    	}
    	public String getStuNo() {
    		return stuNo;
    	}
    	public void setStuNo(String stuNo) {
    		this.stuNo = stuNo;
    	}
    
    }
    

      配置xml文件:<bean-class>里面是类的包名+类名

    <?xml version="1.0" encoding="UTF-8"?>
    <beans>
    
        <bean>
            <bean-name>user</bean-name>
            <bean-class>com.bwf.test.User</bean-class>
            <init>
                <property name="userName">zhangsan</property>
                <property name="userAge">18</property>
                <property name="userPwd">123456</property>
            </init>
        </bean>
        
        <bean>
            <bean-name>user1</bean-name>
            <bean-class>com.bwf.test.User</bean-class>
            <init>
                <property name="userName">lisi</property>
                <property name="userPwd">654321</property>
                <property name="userAge">24</property>
            </init>
        </bean>
        
        <bean>
            <bean-name>student</bean-name>
            <bean-class>com.bwf.test.Student</bean-class>
            <init>
                <property name="stuName">wangwu</property>
                <property name="stuNo">1</property>
            </init>
        </bean>    
    </beans>

    解析xml为对象赋值及测试:

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.InputStream;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.List;
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    import com.bwf.test.Student;
    import com.bwf.test.User;
    
    public class XMLRefelct {
    
    	public static void main(String[] args) {
    		try {
    			readXML();
    		} catch (Exception e) {			
    			e.printStackTrace();
    		}
    	}
    	/**
    	 * 读xml 文件
    	 * @throws Exception
    	 */
    	public static void readXML() throws Exception{		
    		InputStream in = null;
    		try {
    			in = new FileInputStream(new File("src/spring.xml"));
    		} catch (FileNotFoundException e) {			
    			e.printStackTrace();
    		}		
    		SAXReader reader = new SAXReader();		
    		try {
    			Document document = reader.read(in);   //读xml
    			Element root = document.getRootElement();			
    			List<Element> beans = root.elements();	//获取xml中的所有<bean>		
    			for(Element bean : beans){
    				bean.element("bean-class").getStringValue(); //获取配置的类的全路径名  
    										//   <bean-class>com.bwf.test.User</bean-class>
    				//System.out.println(bean.element("bean-class").getStringValue());
    				//通过全路径名 反射得到Class 对象
    				Class<?> c = Class.forName(bean.element("bean-class").getStringValue()); 
    				
    				List<Element> properties = bean.element("init").elements("property");//获取配置里面的所有属性
    				
    				Object o = c.newInstance(); //反射创建对象
    				
    				for(Element property : properties){					
    					//判断属性是否在类的属性中存在      并为对象初始化配置的值
    					o = checkPropertyEsxit(property.attribute("name").getStringValue(),o,c,property.getStringValue());				
    				}	
    				
    				test(o);	//调用测试方法	
    			}			
    		} catch (DocumentException e) {
    			
    			e.printStackTrace();
    		}
    	}
    	/**
    	 * 判断属性是否在类的属性中存在      并为对象初始化配置的值
    	 * @param propertyName
    	 * @param o
    	 * @param c
    	 * @param propertyValue
    	 * @return
    	 */
    	public static Object checkPropertyEsxit(String propertyName,Object o ,Class<?> c,String propertyValue ){
    		
    		Field[] fields = c.getDeclaredFields();
    		
    		boolean isExsit = false;//初始化为不存在
    		
    		for(Field field:fields){
    			
    			if(field.getName().equals(propertyName)){
    				//说明属性存在
    				isExsit = true;
    				//拼接set方法的规范名字
    				String setMethod = "set"+String.valueOf(field.getName().charAt(0)).toUpperCase()+
    						field.getName().substring(1);
    				try {
    					//获取set方法
    					Method m = c.getDeclaredMethod(setMethod, field.getType());
    					
    					try {
    						//调用set方法初始化属性的值
    						m.invoke(o, new Object[]{propertyValue});
    						
    					} catch (IllegalAccessException e) {						
    						e.printStackTrace();
    					} catch (IllegalArgumentException e) {						
    						e.printStackTrace();
    					} catch (InvocationTargetException e) {		
    						e.printStackTrace();
    					}										
    				} catch (NoSuchMethodException e) {					
    					e.printStackTrace();
    				} catch (SecurityException e) {					
    					e.printStackTrace();
    				}				
    			}
    		}		
    		if(isExsit){
    //			System.out.println(propertyName+"存在");
    			
    		}else{
    //			System.out.println(propertyName+"不存在");
    			 try {
    				throw new NoSuchFieldException(propertyName + "属性不存在" );
    				
    			} catch (NoSuchFieldException e) {				
    				e.printStackTrace();
    			}
    		}		
    		return o;
    	}
    	
    	/**
    	 * 测试对象是否已经初始化
    	 * @param o
    	 */
    	public static  void test(Object o ){				
    		if(o instanceof User){
    			User user = (User)o;
    			System.out.println(user.getUserName());
    			System.out.println(user.getUserPwd());
    			System.out.println(user.getUserAge());
    			System.out.println("----------------");
    		}else if(o instanceof Student){
    			Student s = (Student)o;
    			System.out.println(s.getStuNo());
    		}
    	}
    }
    

      

    结果:配置了两个user 一个 Student 输出了两个user的信息和student的信息

     

  • 相关阅读:
    SourceInsight中文字体
    Android Studio导入第三方类库的方法
    Unable to create Debug Bridge:Unable to start adb server:error:cannot parse version
    match_parent 、 fill_parent 、 wrap_content
    android:textAppearance
    AndroidManifest配置之uses-sdk
    从Github上下载了项目,导入Android Studio,gradle 报错,应该怎么修改
    Android Studio 使用Gradle多渠道打包
    Android Studio常用快捷键
    在一个form表单中根据不同按钮实现多个action事件
  • 原文地址:https://www.cnblogs.com/nijunyang/p/7525768.html
Copyright © 2020-2023  润新知