1. 程式人生 > >Java反射機制模擬Spring IOC容器

Java反射機制模擬Spring IOC容器

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);
	}

}