java反射机制模拟Spring Ioc实现
前言
用Spring也有两年多时间了,一直以来都没时间深入研究它的内部实现机制。现在有时间开始研究Spring的Ioc,当然,说到Spring就让人想到Ioc和Aop了。本篇文章是利用java的反射机制模拟Ioc实现。
IoC理论的背景
在采用面向对象方法设计的软件系统中,底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑。即软件系统中对象之间的耦合,对象A和对象B之间有关联,对象B又和对象C有依赖关系,这样对象和对象之间有着复杂的依赖关系,所以才有了控制反转这个理论。
反射机制模拟Ioc
步骤:
第一步:定义服务的配置文件(指定服务名和服务路径)
<?xml version="1.0" encoding="utf-8" ?>
<!-- DOCTYPE service - config SYSTEM " service.dtd " -->
<beans>
<!-- 用户服务 -->
<bean name="UserService " class="com.ioc.service.UserService" template="normal" />
<bean name="GnmkService" class="com.ioc.service.GoServiceImpl" template= "normal" />
</beans>
第二步:服务 初始化时将所有服务名和路径加载到一个静态的HashMap中
public class ServiceConfig {
//启动服务时,需要将配置文件的信息读取放到serviceMap中。
public static HashMap serviceMap = new HashMap();
public static String getService(String serviceName) {
serviceMap = (HashMap) prepareServiceMap();
String serviceClass= "";
serviceClass= ServiceConfig.serviceMap.get(serviceName).toString();
return serviceClass;
}
private static Map prepareServiceMap() {
Map map = null;
BeanFactory factory = new BeanFactory();
try {
map = factory.init("service.xml");
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
public static void init(){
BeanFactory factory = new BeanFactory();
try {
factory.init("service.xml");
} catch (Exception e) {
e.printStackTrace();
}
}
}
第三步:定义一个service接口
public interface Service {
public void execute();
}
第四步:服务实例化
public class ServiceExecuteHelper {
public static void execute(String serviceName) {
try {
//验证服务是否存在
String servicClass = ServiceConfig.getService(serviceName);
//如果服务存在就加载服务信息
if (servicClass != null && !servicClass.equals("")) {
Class<?> classObject = Class.forName(servicClass);
Service service = (Service) classObject.newInstance();
service.execute();
} else{
System.out.println("服务" + serviceName + "未定义");
}
}catch(Exception e) {
e.printStackTrace();
System.out.println("服务" + serviceName + "不存在");
}
}
}
第五步:定义接口具体服务并实现接口类
public class GoServiceImpl implements Service{
@Override
public void execute() {
System.out.println("执行的是GoServiceImpl");
}
}
第六步:测试类
public class Test {
public static void main(String[] args) {
ServiceExecuteHelper.execute("UserService");
}
}
第七步:提供装配服务的类
public class BeanFactory {
private Map<String, Object> beanMap = new HashMap<String, Object>();
/**
* 初始化配置文件.
* @param xml
* @throws Exception
*/
public Map init(String xml) throws Exception {
//读取指定的配置文件
SAXReader reader = new SAXReader();
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
//从class目录下获取指定的xml文件
InputStream ins = classLoader.getResourceAsStream(xml);
Document doc = reader.read(ins);
Element root = doc.getRootElement();
Element foo;
//遍历bean
for (Iterator i = root.elementIterator("bean"); i.hasNext();) {
foo = (Element) i.next();
//获取bean的属性id和class
Attribute id = foo.attribute("id");
Attribute cls = foo.attribute("class");
//利用Java反射机制,通过class的名称获取Class对象
Class bean = Class.forName(cls.getText());
//获取对应class的信息
java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean);
//获取其属性描述
java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors();
//设置值的方法
Method mSet = null;
//创建一个对象
Object obj = bean.newInstance();
//遍历该bean的property属性
for (Iterator ite = foo.elementIterator("property"); ite.hasNext();) {
Element foo2 = (Element) ite.next();
//获取该property的name属性
Attribute name = foo2.attribute("name");
String value = null;
//获取该property的子元素value的值
for(Iterator ite1 = foo2.elementIterator("value"); ite1.hasNext();) {
Element node = (Element) ite1.next();
value = node.getText();
break;
}
for (int k = 0; k < pd.length; k++) {
if (pd[k].getName().equalsIgnoreCase(name.getText())) {
mSet = pd[k].getWriteMethod();
//利用Java的反射极致调用对象的某个set方法,并将值设置进去
mSet.invoke(obj, value);
}
}
}
//将对象放入beanMap中,其中key为id值,value为对象
beanMap.put(id.getText(), obj);
}
return beanMap;
}
/**
* 通过bean的id获取bean的对象.
* @param beanName bean的id
* @return 返回对应对象
*/
public Object getBean(String beanName) {
Object obj = beanMap.get(beanName);
return obj;
}
}