通过反射模拟spring实例化bean的小例子

 

Spring是通过org.springframework.context.support.ClassPathXmlApplicationContext来实例化bean的对象,然后供其他的对象进行调用。这个例子就是模拟java实例化Bean的这个过程。

 

主要用相关技术:反射,XML,jdom。

 

操作步骤:

1, 构建能够读取xml配置文件,并且能够实例化Bean的类ClassPathXmlApplicationContext.java

       (通过jdom读取配置文件信息,然后通过反射实例化类)

2, 准备Bean.xml配置文件,配置需要实例化类

3, 准备具体的实体类(Bean.xml配置的类)

4, 准备测试类,进行功能验证。

 

目的:

1, 更加深入了解Spring实例化的Bean的机制。

2, 扩展使用,不使用spring框架可以通过配置文件来决定需要实例化的类,而不用修改类本身。

 

废话少说,上代码了。

 

1, 创建ClassPathXmlApplicationContext.java, 为了便于扩展该类继承了BeanFactory接口

抽象一个BeanFactory的接口

 

 

package com.lch.spring;

public interface BeanFactory
{
	public Object  getBean(String id);
}

 

 

 

继承Bean的接口,创建ClassPathXmlApplicationContext 来模拟实例化Bean的过程

 

 

package com.lch.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;

//模拟spring读取配置文件,生成对象实例的方式。
public class ClassPathXmlApplicationContext implements BeanFactory
{
	private Map<String, Object> beans = new HashMap<String, Object>();

	public ClassPathXmlApplicationContext() throws Exception,
			InstantiationException, IllegalAccessException,
			ClassNotFoundException
	{
		SAXBuilder sb = new SAXBuilder();

		Document doc = sb.build(this.getClass().getClassLoader()
				.getResourceAsStream("beans.xml"));
		Element root = doc.getRootElement();

		@SuppressWarnings("rawtypes")
		List list = root.getChildren("bean");

		for (int i = 0; i < list.size(); i++)
		{
			Element element = (Element) list.get(i);
			String id = element.getAttributeValue("id");
			String clazz = element.getAttributeValue("class");

			Object o = Class.forName(clazz).newInstance();

			beans.put(id, o);
			
			for(Element propertyElement : (List<Element>) element.getChildren("property"))
			{
				String name = propertyElement.getAttributeValue("name");
				String bean = propertyElement.getAttributeValue("bean");
				
				Object beanObject = beans.get(bean);
				
				String methondName = "set"+name.substring(0, 1).toUpperCase() + name.substring(1);
				
				Method m = o.getClass().getMethod(methondName, beanObject.getClass().getInterfaces()[0]);
				
				m.invoke(o, beanObject);
				
//				beanObject.getClass().
			}

		}

	}

	@Override
	public Object getBean(String id)
	{
		return beans.get(id);
	}

}

 

验证ClassPathXmlApplicationContext  执行效果。

 

2,创建一个bean.xml的文件,配置关联关系。

 

<beans>
	<bean id="u" class="com.lch.dao.impl.UserDAO" />
	
	<bean id="userService" class="com.lch.service.UserService" >  
		<property name="userDAO" bean="u"/>
	</bean>
	
</beans>

 

 3, 构建实体类,具体实现的方法

 

package com.lch.dao

import com.lch.dao.UserDAO;
import com.lch.model.User;

public class UserDAO
{
	@Override
	public void save(User user)
	{
		// TODO Auto-generated method stub
		System.out.println("User save!!!! user = "+user.getUsername() +" , password = "+user.getPassword() );
	}
}
 
package com.lch.model;

public class User
{
	private String username;
	private String password;

	public String getUsername()
	{
		return username;
	}

	public void setUsername(String username)
	{
		this.username = username;
	}

	public String getPassword()
	{
		return password;
	}

	public void setPassword(String password)
	{
		this.password = password;
	}

}
  
package com.lch.service;

import com.lch.dao.UserDAO;
import com.lch.model.User;

public class UserService
{
	private UserDAO userDAO;
	
	public void add(User user)
	{
		userDAO.save(user);
	}

	public UserDAO getUserDAO()
	{
		return userDAO;
	}

	public void setUserDAO(UserDAO userDAO)
	{
		this.userDAO = userDAO;
	}
	
}
 

 

4, 验证ClassPathXmlApplicationContext  执行效果。

 

package com.lch.service;

import org.junit.Test;

import com.lch.model.User;
import com.lch.spring.BeanFactory;
import com.lch.spring.ClassPathXmlApplicationContext;

public class UserServiceTest
{

	@Test
	public void testAdd() throws Exception
	{
		BeanFactory applicationContext = new ClassPathXmlApplicationContext();
		UserService service = (UserService) applicationContext
				.getBean("userService");

		User user = new User();
		user.setUsername("jack zhang");
		user.setPassword("zhang password");

		service.add(user);
	}
}
 

 

验证结果:
User save!!!! user = jack zhang , password = zhang password

你可能感兴趣的:(spring)