反射-Spring管理Bean,注入Bean属性的反射机制。
#反射
1.是JAVA API,是Java提供的现成的类!!
--接受API提供的功能!
2. 是Java提供的动态执行机制,动态加载类,动态创建对象,动态访问属性,动态调用方法。
##反射用途
1. eclipse 中解析类的结构使用了反射
2.JUnit识别被测试方法使用了反射
-- JUnit3 利用了反射查找test开头的方法
-- JUnit4 利用了反射解析@Test查找测试方法
3.Spring 管理Bean对象,注入Bean属性使用了反射
--利用反射创建Bean对象实例
--利用反射注入Bean的属性
4.注解的解析使用了反射
--利用反射API支持注解
5. 强行执行私有方法(访问私有属性)
分析图解:
CLASS--package: main/springstru 、main/resources
------------------------------ 分割线 -----------------------
springstru/ApplicationContext.java
package springstru; import java.io.InputStream; import java.util.HashMap; import java.util.List; import java.util.Map; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class ApplicationContext { //是缓存Spring容器的Bean对象 private Map<String,Object> beans = new HashMap<String, Object>(); /** * 利用配置文件初始化当前容器 * 利用xml配置文件,初始化全部的Bean对象 */ public ApplicationContext(String xml) throws Exception{ //利用DOM4j,读取xml文件 //解析XML文件内容,得到Bean的类名和Bean的ID: //根据类名动态加载类并且创建对象, //将对象和对应的ID添加到map中 //从Resource(classpath)中读取流 InputStream in = getClass().getClassLoader().getResourceAsStream(xml); SAXReader reader = new SAXReader(); Document doc = reader.read(in); in.close(); //解析xml :<beans><bean><bean><bean><bean>..... Element root = doc.getRootElement(); //读取根元素中全部的bean子元素 List<Element> list = root.elements("bean"); for(Element e:list){ //e 就是bean元素id属性和class属性 String id = e.attributeValue("id"); String className = e.attributeValue("class"); //动态加载类,动态创建对象 Class cls = Class.forName(className); Object bean = cls.newInstance(); beans.put(id,bean); } } public Object getBean(String id){ //根据id在map查找对象,并返回对象 return beans.get(id); } //使用泛型方法:优点是可以减少一次类型转换 public<T> T getBean(String id,Class<T> cls){ return (T)beans.get(id); } }
------------------------------ 分割线 -----------------------
springstru/Demo.java
package springstru; public class Demo { public static void main(String[] args) throws Exception{ ApplicationContext ctx = new ApplicationContext("spring-context.xml"); Foo foo = (Foo)ctx.getBean("foo"); Foo f2 = ctx.getBean("foo", Foo.class); System.out.println(foo); System.out.println(f2); } }
------------------------------ 分割线 -----------------------
/resources/spring-context.xml
<beans> <!-- 配置bean元素 --> <bean id="foo" class="springstru.Foo"></bean> <bean id="date" class="java.util.Date"></bean> <bean id="testCase" class="demo.TestCase"></bean> </beans>