天天看點

SpringIoc原理分析(手把手教你自制springioc架構)手寫SpringIOC架構

手寫SpringIOC架構

什麼是SpringIOC

什麼是SpringIOC,就是把每一個bean(實體類)與bean(實體了)之間的關系交給第三方容器進行管理。

Xml配置:

<beans>
	<bean id="user1" class="com.itmayiedu.entity.UserEntity">
		<property name="userId" value="0001"></property>
		<property name="userName" value="何傑"></property>
	</bean>
	<bean id="user2" class="com.itmayiedu.entity.UserEntity">
		<property name="userId" value="0002"></property>
		<property name="userName" value="張三"></property>
	</bean>
</beans>
           

Java代碼:

//1.讀取springxml配置
		ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		//2.擷取bean對象
		TestService testService = (TestService) classPathXmlApplicationContext.getBean("testService");
		System.out.println(testService.test());
           

什麼是SpringIOC底層實作原理

  • 1.讀取bean的XML配置檔案
  • 2.使用beanId查找bean配置,并擷取配置檔案中class位址。
  • 3.使用Java反射技術執行個體化對象
  • 4.擷取屬性配置,使用反射技術進行指派。

    詳細步驟

1.利用傳入的參數擷取xml檔案的流,并且利用dom4j解析成Document對象
2.對于Document對象擷取根元素對象<beans>後對下面的<bean>标簽進行周遊,判斷是否有符合的id.
3.如果找到對應的id,相當于找到了一個Element元素,開始建立對象,先擷取class屬性,根據屬性值利用反射建立對象.
4.周遊<bean>标簽下的property标簽,并對屬性指派.注意,需要單獨處理int,float類型的屬性.因為在xml配置中這些屬性都是以字元串的形式來配置的,是以需要額外處理.
5.如果屬性property标簽有ref屬性,說明某個屬性的值是一個對象,那麼根據id(ref屬性的值)去擷取ref對應的對象,再給屬性指派.
6.傳回建立的對象,如果沒有對應的id,或者<beans>下沒有子标簽都會傳回null
           

建立實體類

public class User {

	private String userId;
	private String userName;
	public String getUserId() {
		return userId;
	}
	public void setUserId(String userId) {
		this.userId = userId;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
}
           

使用反射技術完成Java代碼

public class ClassPathXmlApplicationContext {
	private String pathXml = null;

	public ClassPathXmlApplicationContext(String pathXml) {
		this.pathXml = pathXml;
	}

	public Object getBean(String beanId) throws Exception {
		if (StringUtils.isEmpty(beanId)) {
			throw new Exception("beanId is null");
		}
		SAXReader saxReader = new SAXReader();
		Document read = saxReader.read(this.getClass().getClassLoader().getResource(pathXml));
		// 擷取到根節點
		Element rootElement = read.getRootElement();
		// 根節點下所有的子節點
		List<Element> elements = rootElement.elements();
		for (Element element : elements) {
			// 擷取到節點上的屬性
			String id = element.attributeValue("id");
			if (StringUtils.isEmpty(id)) {
				continue;
			}
			if (!id.equals(beanId)) {
				continue;
			}

			// 使用java反射機制初始化對象
			String beanClass = element.attributeValue("class");
			Class<?> forName = Class.forName(beanClass);
			Object newInstance = forName.newInstance();
			List<Element> propertyElementList = element.elements();
			for (Element el : propertyElementList) {
				String name = el.attributeValue("name");
				String value = el.attributeValue("value");
				Field declaredField = forName.getDeclaredField(name);
				declaredField.setAccessible(true);
				declaredField.set(newInstance, value);
			}
			return newInstance;

		

		}
		return null;
	}

	public static void main(String[] args) throws Exception {
		ClassPathXmlApplicationContext classPath = new ClassPathXmlApplicationContext("applicationContext.xml");
		User user = (User) classPath.getBean("user2");
		System.out.println(user.getUserId() + "---" + user.getUserName());
	}
}
           

Maven坐标

<dependencies>
		<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.4</version>
		</dependency>
		<dependency>
			<groupId>org.dom4j</groupId>
			<artifactId>dom4j</artifactId>
			<version>2.0.0</version>
		</dependency>
	</dependencies>
           

繼續閱讀