java反照应用
java反射应用
定义
反射平时只管拿来用用,真的要给其下个定义,我还真总结不好,不过之前到看到一个比较好的定义:反射就是把java类中的各个成分映射成相应的java类。
谈到类,我们说java中类的概念本身就是为了让我们更好的去模拟现实社会,比如说模拟人,我们会写出Person类;车我们会写出Car类……。那我们有没有想过,这么多我们写出来的类,我们应该用什么类来表示哪? 这样就很容易的引出了Class这个类。
看看两种类型的对比:
普通类(Person,Car) :new 类名();这个时候JVM为对象分配堆内存中。
Class类:Class.forname(“类名”),将编译好的二进制文件存储到方法区中。
更多的我们可以去了解JVM的体系结构<深入java虚拟机>
下面看看如何获取到class对象
1. 通过普通类对象获取 ,例如Date d=new Date(); Class cl=d.getClass();
2. 可以调用静态方法forName()获得类名对应的class对象
例如:String className="java.util.Date";
Class cl=Class.forName(className);
3.通过普通类获得 例如Class cl=Date.class
有了class这个对象,我们就可以对我们的普通类做任何我们想做的事情了,主要围绕:
Field,Method,Constructor分别用来描述类的域,方法和构造器.
具体细节我们可以参考JDK API
实例1:struts2
这个拦截器是我们经常要用到的,主要是用于将前台的参数封装到我们的bean里面。
在配置文件中指定好我们的Bean=”boKe.reflect.struts.Person”,要求Bean提供一个无参的构造函数,并且给属性提供set方法。
实例2:Spring
Spring中运用反射帮助我们处理的依赖注入的问题(包括XML形式和注解的形式)
定义
反射平时只管拿来用用,真的要给其下个定义,我还真总结不好,不过之前到看到一个比较好的定义:反射就是把java类中的各个成分映射成相应的java类。
谈到类,我们说java中类的概念本身就是为了让我们更好的去模拟现实社会,比如说模拟人,我们会写出Person类;车我们会写出Car类……。那我们有没有想过,这么多我们写出来的类,我们应该用什么类来表示哪? 这样就很容易的引出了Class这个类。
看看两种类型的对比:
普通类(Person,Car) :new 类名();这个时候JVM为对象分配堆内存中。
Class类:Class.forname(“类名”),将编译好的二进制文件存储到方法区中。
更多的我们可以去了解JVM的体系结构<深入java虚拟机>
下面看看如何获取到class对象
1. 通过普通类对象获取 ,例如Date d=new Date(); Class cl=d.getClass();
2. 可以调用静态方法forName()获得类名对应的class对象
例如:String className="java.util.Date";
Class cl=Class.forName(className);
3.通过普通类获得 例如Class cl=Date.class
有了class这个对象,我们就可以对我们的普通类做任何我们想做的事情了,主要围绕:
Field,Method,Constructor分别用来描述类的域,方法和构造器.
具体细节我们可以参考JDK API
实例1:struts2
<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
这个拦截器是我们经常要用到的,主要是用于将前台的参数封装到我们的bean里面。
在配置文件中指定好我们的Bean=”boKe.reflect.struts.Person”,要求Bean提供一个无参的构造函数,并且给属性提供set方法。
package boKe.reflect.struts; public class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString(){ return "姓名:"+name+",年龄:"+age; } }
package boKe.reflect.struts; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.apache.commons.beanutils.ConvertUtils; public class Main { public static void main(String[] args) throws Exception { // request,获取的消息都是String类型 Map<String, String> paramMap = new HashMap<String, String>(); paramMap.put("name", "zhaohui"); paramMap.put("age", "25"); // 加载类,实例化对象 Object person = Class.forName("boKe.reflect.struts.Person").newInstance(); // 处理参数 PropertyDescriptor[] ps = Introspector.getBeanInfo(person.getClass()) .getPropertyDescriptors(); Object value = null; for (PropertyDescriptor propertyDescriptor : ps) { Method setter = propertyDescriptor.getWriteMethod();// 获取属性的setter方法 if (setter != null) { value = ConvertUtils.convert( paramMap.get(propertyDescriptor.getName()), propertyDescriptor.getPropertyType()); setter.invoke(person, value); } } System.out.println(person.toString()); } }
实例2:Spring
Spring中运用反射帮助我们处理的依赖注入的问题(包括XML形式和注解的形式)
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="personDao" class="boKe.reflect.spring.PersonDao"></bean> <bean id="personService" class="boKe.reflect.spring.PersonService"> <property name="personDao" ref="personDao"></property> </bean> </beans>
package boKe.reflect.spring; public class PropertyDefinition { private String name; private String ref; private String value; public PropertyDefinition(String name, String ref) { super(); this.name = name; this.ref = ref; } public PropertyDefinition(String name, String ref, String value) { super(); this.name = name; this.ref = ref; this.value = value; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getRef() { return ref; } public void setRef(String ref) { this.ref = ref; } }
package boKe.reflect.spring; import java.util.ArrayList; import java.util.List; public class BeanDefinition { private String id; private String className; private List<PropertyDefinition> propertys=new ArrayList<PropertyDefinition>(); public BeanDefinition(String id, String className) { this.id = id; this.className = className; } public List<PropertyDefinition> getPropertys() { return propertys; } public void setPropertys(List<PropertyDefinition> propertys) { this.propertys = propertys; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } }
package boKe.reflect.spring; public class PersonDao { public String getName(){ return "zhaohui"; } }
package boKe.reflect.spring; public class PersonService { private PersonDao personDao; public String getName() { return personDao.getName(); } public PersonDao getPersonDao() { return personDao; } public void setPersonDao(PersonDao personDao) { this.personDao = personDao; } }
package boKe.reflect.spring; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.beanutils.ConvertUtils; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class XmlApplicationContext { private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>(); private Map<String, Object> sigletons = new HashMap<String, Object>(); public XmlApplicationContext(String fileName) { readXmlFile(fileName); instanceBeans(); injectObject(); } public Object getBean(String beanName) { return this.sigletons.get(beanName); } /** * 读取xml * * @param fileName * 文件名 */ private void readXmlFile(String fileName) { SAXReader saxReader = new SAXReader(); Document doucment = null; try { doucment = saxReader.read(this.getClass().getResourceAsStream( fileName)); } catch (DocumentException e) { e.printStackTrace(); } List<Element> beans = doucment.getRootElement().elements(); for (Element bean : beans) { String id = bean.attributeValue("id"); String clazz = bean.attributeValue("class"); BeanDefinition beanDefine = new BeanDefinition(id, clazz); List<Element> propertys = bean.elements(); for (Element property : propertys) { String propertyName = property.attributeValue("name"); String propertyRef = property.attributeValue("ref"); String propertyValue = property.attributeValue("value"); PropertyDefinition propertyDefinition = new PropertyDefinition( propertyName, propertyRef, propertyValue); beanDefine.getPropertys().add(propertyDefinition); } beanDefines.add(beanDefine); } } /*** * 完成实例化对象 */ private void instanceBeans() { for (BeanDefinition beanDefinition : beanDefines) { if (beanDefinition.getClassName() != null && !"".equals(beanDefinition.getClassName().trim())) { try { sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()) .newInstance()); } catch (Exception e) { e.printStackTrace(); } } } } /** * 为bean对象的属性注入值 */ private void injectObject() { for (BeanDefinition beanDefinition : beanDefines) { Object bean = sigletons.get(beanDefinition.getId()); if (bean != null) { try { // 获取当前对象所有的属性 PropertyDescriptor[] ps = Introspector.getBeanInfo( bean.getClass()).getPropertyDescriptors(); for (PropertyDefinition propertyDefinition : beanDefinition .getPropertys()) { for (PropertyDescriptor propertyDescriptor : ps) { // 用于比较当前在xml文件中配置的属性是否也在获取的对象的属性中 if (propertyDefinition.getName().equals( propertyDescriptor.getName())) { Method setter = propertyDescriptor .getWriteMethod();// 获取属性的setter方法 if (setter != null) { Object value = null; if (propertyDefinition.getRef() != null && !propertyDefinition.getRef() .equals("")) { value = sigletons .get(propertyDefinition .getRef()); } else { // 类型的转换将字符串类型转化为基本类型 value = ConvertUtils.convert( propertyDefinition.getValue(), propertyDescriptor .getPropertyType()); } // 如果setter方法是private setter.setAccessible(true); setter.invoke(bean, value); } } } } } catch (Exception e) { e.printStackTrace(); } } } } }
package boKe.reflect.spring; public class Main { public static void main(String[] args) { XmlApplicationContext context=new XmlApplicationContext("bean.xml"); PersonService service=(PersonService) context.getBean("personService"); System.out.println(service.getName()); } }