IOC容器相关类
- BeanFactory接口
在该接口中定义IOC容器的统一规范即获取bean对象。
public interface BeanFactory {
//根据bean对象的名称获取bean对象
Object getBean(String name) throws Exception;
//根据bean对象的名称获取bean对象,并进行类型转换
T getBean(String name, Class extends T> clazz) throws Exception;
}
- ApplicationContext接口
该接口的所以的子实现类对bean对象的创建都是非延时的,所以在该接口中定义 refresh() 方法,该方法主要完成以下两个功能:
- 加载配置文件。
- 根据注册表中的BeanDefinition对象封装的数据进行bean对象的创建。
public interface ApplicationContext extends BeanFactory {
//进行配置文件加载并进行对象创建
void refresh() throws IllegalStateException, Exception;
}
- AbstractApplicationContext类
- 作为ApplicationContext接口的子类,所以该类也是非延时加载,所以需要在该类中定义一个Map集合,作为bean对象存储的容器。
- 声明BeanDefinitionReader类型的变量,用来进行xml配置文件的解析,符合单一职责原则。BeanDefinitionReader类型的对象创建交由子类实现,因为只有子类明确到底创建BeanDefinitionReader哪儿个子实现类对象。
public abstract class AbstractApplicationContext implements ApplicationContext {
protected BeanDefinitionReader beanDefinitionReader;
//用来存储bean对象的容器 key存储的是bean的id值,value存储的是bean对象
protected Map singletonObjects = new HashMap();
//存储配置文件的路径
protected String configLocation;
public void refresh() throws IllegalStateException, Exception {
//加载BeanDefinition
beanDefinitionReader.loadBeanDefinitions(configLocation);
//初始化bean
finishBeanInitialization();
}
//bean的初始化
private void finishBeanInitialization() throws Exception {
BeanDefinitionRegistry registry =
beanDefinitionReader.getRegistry();
String[] beanNames = registry.getBeanDefinitionNames();
for (String beanName : beanNames) {
BeanDefinition beanDefinition =registry.getBeanDefinition(beanName);
getBean(beanName);
}
}
}
- ClassPathXmlApplicationContext类
该类主要是加载类路径下的配置文件,并进行bean对象的创建,主要完成以下功能:
- 在构造方法中,创建BeanDefinitionReader对象。
- 在构造方法中,调用refresh()方法,用于进行配置文件加载、创建bean对象并存储到容器中。
- 重写父接口中的getBean()方法,并实现依赖注入操作。
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.support.AbstractApplicationContext;
import java.lang.reflect.Method;
public class ClassPathXmlApplicationContext extends
AbstractApplicationContext {
public ClassPathXmlApplicationContext(String configLocation) {
this.configLocation = configLocation;
//构建XmlBeanDefinitionReader对象
beanDefinitionReader = new XmlBeanDefinitionReader();
try {
this.refresh();
} catch (Exception e) {
}
}
//根据bean的id属性值获取bean对象
@Override
public Object getBean(String name) throws Exception {
//return singletonObjects.get(name);
Object obj = singletonObjects.get(name);
if(obj != null) {
return obj;
}
BeanDefinitionRegistry registry =
beanDefinitionReader.getRegistry();
BeanDefinition beanDefinition = registry.getBeanDefinition(name);
if(beanDefinition == null) {
return null;
}
String className = beanDefinition.getClassName();
Class> clazz = Class.forName(className);
Object beanObj = clazz.newInstance();
MutablePropertyValues propertyValues =
beanDefinition.getPropertyValues();
for (PropertyValue propertyValue : propertyValues) {
String propertyName = propertyValue.getName();
String value = propertyValue.getValue();
String ref = propertyValue.getRef();
if(ref != null && !"".equals(ref)) {
Object bean = getBean(ref);
String methodName =
StringUtils.getSetterMethodNameByFieldName(propertyName);
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if(method.getName().equals(methodName)) {
method.invoke(beanObj,bean);
}
}
}
if(value != null && !"".equals(value)) {
String methodName =
StringUtils.getSetterMethodNameByFieldName(propertyName);
Method method = clazz.getMethod(methodName, String.class);
method.invoke(beanObj,value);
}
}
singletonObjects.put(name,beanObj);
return beanObj;
}
@Override
public T getBean(String name, Class extends T> clazz) throws
Exception {
Object bean = getBean(name);
if(bean != null) {
return clazz.cast(bean);
}
return null;
}
}