Java反射機制模擬Spring IOC容器
阿新 • • 發佈:2019-02-10
Ref:
java反射機制
package reflection; import java.lang.reflect.Method; public class InvokeTest { public String add(int param1, int param2) { return param1 + " + " + param2 + " = " + (param1 + param2); } public String sayHi(String message) { return "hi " + message; } public String objectToString(Method method) { return method.toString(); } public static void main(String[] args) throws Exception { // 常規執行方式 InvokeTest invokeTest1 = new InvokeTest(); System.out.println(invokeTest1.add(1, 2)); System.out.println(invokeTest1.sayHi("jack")); // 第一步:獲取Class物件,方式:1、使用Class類的靜態方法;2、使用類的.class語法;3、使用物件的getClass()方法 Class<?> clazz; clazz = InvokeTest.class; clazz = Class.forName("reflection.InvokeTest"); InvokeTest invokeTest = new InvokeTest(); clazz = invokeTest.getClass(); // 第二步:生成新的物件 Object invokeTest2 = clazz.newInstance(); System.out.println(invokeTest2 instanceof InvokeTest); // 第三步:通過反射呼叫方法,首先獲得與該方法對應的Method物件 // 第一個引數是要呼叫的方法名,第二個引數是該方法所需要的引數的Class物件陣列 Method addMethod = invokeTest2.getClass().getMethod("add", new Class[] { int.class, int.class }); Method sayHiMethod = invokeTest2.getClass().getMethod("sayHi", new Class[] { String.class }); Method objectToStringMethod = invokeTest2.getClass().getMethod("objectToString", new Class[] { Method.class }); // 單一引數的也可以這樣,多引數的需要用 new Class[] {} sayHiMethod = invokeTest2.getClass().getMethod("sayHi", String.class); objectToStringMethod = invokeTest2.getClass().getMethod("objectToString", Method.class); // 第四步:呼叫方法 String addResult = (String) addMethod.invoke(invokeTest2, new Object[] { 3, 2 }); System.out.println(addResult); String sayHiResult = (String) sayHiMethod.invoke(invokeTest2, "rose"); System.out.println(sayHiResult); String objectToStringResult = (String) objectToStringMethod.invoke(invokeTest2, objectToStringMethod); System.out.println(objectToStringResult); } }
執行結果:
1 + 2 = 3
hi jack
true
3 + 2 = 5
hi rose
public java.lang.String reflection.InvokeTest.objectToString(java.lang.reflect.Method)
模擬Spring IOC容器
package com.xxr.spring; import java.lang.reflect.Method; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.input.SAXBuilder; public class ClassPathXmlApplicationContext implements BeanFactory { private Map<String, Object> beans = new HashMap<String, Object>(); public ClassPathXmlApplicationContext() throws Exception { SAXBuilder sBuilder = new SAXBuilder(); Document document = sBuilder.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml")); Element root = document.getRootElement(); List elementList = root.getChildren("bean"); for (int i = 0; i < elementList.size(); i++) { Element element = (Element) elementList.get(i); String id = element.getAttributeValue("id"); String clazz = element.getAttributeValue("class"); System.out.println(id + ":" + clazz); Object o = Class.forName(clazz).newInstance(); beans.put(id, o); for (Element propertyElement : element.getChildren()) { String name = propertyElement.getAttributeValue("name"); String bean = propertyElement.getAttributeValue("bean"); Object beanObject = beans.get(bean); String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1); System.out.println("method name = " + methodName); Method method = null; // 兩種方式都可以 method = o.getClass().getMethod(methodName, new Class[]{beanObject.getClass().getInterfaces()[0]}); method = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]); // 兩種方式都可以 method.invoke(o, new Object[]{beanObject}); method.invoke(o, beanObject); } } } @Override public Object getBean(String name) { return beans.get(name); } }
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="u" class="com.xxr.dao.impl.UserDAOImpl" />
<bean id="userService" class="com.xxr.service.UserService">
<property name="userDAO" bean="u" />
</bean>
</beans>
package com.xxr.spring; public interface BeanFactory { public Object getBean(String name); }
package com.xxr.service;
import org.junit.Test;
import com.xxr.model.User;
import com.xxr.spring.BeanFactory;
import com.xxr.spring.ClassPathXmlApplicationContext;
public class UserServiceTest {
@Test
public void testAdd() throws Exception {
BeanFactory beanFactory = new ClassPathXmlApplicationContext();
UserService userService = (UserService) beanFactory.getBean("userService");
User user = new User();
userService.add(user);
}
}