通过反射模拟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
版权声明:本文为iteye_4481原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。