IOC即控制反转,sping通过配置xml文件来创建和维护类和类之间的关系,当需要修改类或参数时只需要修改配置文件而不需要修改程序,这降低了程序中类的耦合性。sping就相当于一个工厂,通过解析xml配置文件获得类的属性,并通过java的反射机制来生成类。
一个sping的简单实例:
定义Person类
class Person
{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString()
{
return name;
}
}
定义Person类,Person类有name属性,实现setter,getter方法
配置xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="person" class="com.tsing.Person">
<property name="name">
<value>Alice</value><!--设置name属性-->
</property>
</bean>
</beans>
配置sping解析的xml文件,为Person类注入name属性
//获取person对象
public static void main(String[] args) throws Exception
{
ApplicationContext ctx = new ClassPathXmlApplicationContext("com/tsing/beans.xml");
System.out.println((Person) ctx.getBean("person"));
}
sping通过解析xml配置文件,使用java的反射机制通过构造函数或set方法为类注入属性,生成类实例,内部通过一个键为String值为Object的HashMap保存生成的实例,当从sping中获取类时即从HashMap中获取String键对应的Object值.
下面模拟sping Ioc的实现:
实现一个Bean对象,用以模拟xml文件,保存设置的类属性
class Bean
{
private String id;//id
private String type;//class
private Map<String, Object> properties = new HashMap<String, Object>();//properties
public void setId(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setType(String type) {
this.type = type;
}
public String getType() {
return type;
}
public void setProperties(Map<String, Object> properties) {
this.properties = properties;
}
public Map<String, Object> getProperties() {
return properties;
}
}
实现bean工厂,用以解析Bean,获取类实例
public class BeanFactory
{
//保存生成的类实例,键为String,值为Object
private Map<String, Object> beanMap = new HashMap<String, Object>();
//构造函数解析配置好的bean,相当于sping中解析xml配置文件
public BeanFactory(List<Bean> beans)
{
try
{
for(Bean bean : beans)
{
Class<?> clazz = Class.forName(bean.getType());
//生成类
Object obj = clazz.newInstance();
Method[] methods = clazz.getMethods();
for(String name : bean.getProperties().keySet())
{
StringBuilder sb = new StringBuilder(name);
sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
String methodName = sb.toString();
methodName = "set" + methodName;
for(Method method : methods)
{
//通过set方法设置类的属性
if(method.getName().equals(methodName))
method.invoke(obj, bean.getProperties().get(name));
}
}
//将生成好的类放入beanMap
beanMap.put(bean.getId(), obj);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
//获得bean
public Object getBean(String id)
{
return beanMap.get(id);
}
public static void main(String[] args)
{
ArrayList<Bean> beans = new ArrayList<Bean>();
Bean bean = new Bean();
//生成bean的配置信息,相当于配置xml文件
bean.setId("person");
bean.setType("Person");
Map<String, Object> properties = new HashMap<String, Object>();
//配置属性
properties.put("name", "Alice");
properties.put("id", 11);
bean.setProperties(properties);
beans.add(bean);
//解析配置好的bean
BeanFactory factory = new BeanFactory(beans);
//获取person类
Person person = (Person) factory.getBean("person");
System.out.println(person);
}
}
运行结果:
Alice
至此,一个简单的sping Ioc模拟告一段落。