com.cn.spring.context.ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String)
加载配置类信息
public ClassPathXmlApplicationContext(String configLocation) throws Exception {
this(configLocation, new AutowireCapableBeanFactory());
}
com.cn.spring.context.ClassPathXmlApplicationContext
public ClassPathXmlApplicationContext(String configLocation, AbstractBeanFactory beanFactory) throws Exception {
super(beanFactory);
this.configLocation = configLocation;
refresh();
}
com.cn.spring.context.AbstractApplicationContext
public AbstractApplicationContext(AbstractBeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
com.cn.spring.context.AbstractApplicationContext#refresh
public void refresh() throws Exception {
// 加载定义的bean
loadBeanDefinitions(beanFactory);
// 注册
registerBeanPostProcessors(beanFactory);
onRefresh();
}
protected abstract void loadBeanDefinitions(AbstractBeanFactory beanFactory) throws Exception;
解析xml开始啦…
// 解析xml
@Override
protected void loadBeanDefinitions(AbstractBeanFactory beanFactory) throws Exception {
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(new ResourceLoader());
xmlBeanDefinitionReader.loadBeanDefinitions(configLocation);
for (Map.Entry<String, BeanDefinition> beanDefinitionEntry : xmlBeanDefinitionReader.getRegistry().entrySet()) {
beanFactory.registerBeanDefinition(beanDefinitionEntry.getKey(), beanDefinitionEntry.getValue());
}
}
读取配置文件第一步: 获取资源文件
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(new ResourceLoader());
com.cn.spring.beans.io.ResourceLoader
public Resource getResource(String location){
URL resource = this.getClass().getClassLoader().getResource(location);
return new UrlResource(resource);
}
doLoadBeanDefinitions(inputStream)
protected void doLoadBeanDefinitions(InputStream inputStream)throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = factory.newDocumentBuilder();
Document doc = docBuilder.parse(inputStream);
// 解析bean
registerBeanDefinitions(doc);
inputStream.close();
}
protected void registerBeanDefinitions(Document doc) {
Element root = doc.getDocumentElement();
parseBeanDefinitions(root);
}
protected void parseBeanDefinitions(Element root) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
processBeanDefinition(ele);
}
}
}
protected void processBeanDefinition(Element ele) {
String name = ele.getAttribute("id");
String className = ele.getAttribute("class");
BeanDefinition beanDefinition = new BeanDefinition();
processProperty(ele, beanDefinition);
beanDefinition.setBeanClassName(className);
getRegistry().put(name, beanDefinition);
}
protected void processProperty(Element ele, BeanDefinition beanDefinition) {
NodeList propertyNode = ele.getElementsByTagName("property");
for (int i = 0; i < propertyNode.getLength(); i++) {
Node node = propertyNode.item(i);
if (node instanceof Element) {
Element propertyEle = (Element) node;
String name = propertyEle.getAttribute("name");
String value = propertyEle.getAttribute("value");
if (value != null && value.length() > 0) {
beanDefinition.getPropertyValues().addPropertyValue(new PropertyValue(name, value));
} else {
String ref = propertyEle.getAttribute("ref");
if (ref == null || ref.length() == 0) {
throw new IllegalArgumentException("Configuration problem: <property> element for property '"
+ name + "' must specify a ref or value");
}
BeanReference beanReference = new BeanReference(ref);
beanDefinition.getPropertyValues().addPropertyValue(new PropertyValue(name, beanReference));
}
}
}
protected void registerBeanPostProcessors(AbstractBeanFactory beanFactory) throws Exception{
List beanPostProcessors = beanFactory.getBeansForType(BeanPostProcessor.class);
for (Object beanPostProcessor : beanPostProcessors) {
beanFactory.addBeanPostProcessor((BeanPostProcessor) beanPostProcessor);
}
}
private void onRefresh() throws Exception{
beanFactory.preInstantiateSingletons();
}
public void preInstantiateSingletons() throws Exception{
for (Iterator it = this.beanDefinitionNames.iterator(); it.hasNext();) {
String beanName = (String) it.next();
getBean(beanName);
}
}
public Object getBean(String name) throws Exception {
BeanDefinition beanDefinition = beanDefinitionMap.get(name);
if (beanDefinition == null) {
throw new IllegalArgumentException("No bean named " + name + " is defined");
}
Object bean = beanDefinition.getBean();
if (bean == null) {
bean = doCreateBean(beanDefinition);
bean = initializeBean(bean, name);
beanDefinition.setBean(bean);
}
return bean;
}
private Object doCreateBean(BeanDefinition beanDefinition)throws Exception {
Object bean = createBeanInstance(beanDefinition);
beanDefinition.setBean(bean);
applyPropertyValues(bean, beanDefinition);
return bean;
}
private Object createBeanInstance(BeanDefinition beanDefinition) throws Exception {
Class beanClass = beanDefinition.getBeanClass();
return beanClass.newInstance();
}
protected void applyPropertyValues(Object bean, BeanDefinition beanDefinition)throws Exception {
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws Exception {
if (bean instanceof AspectJExpressionPointcutAdvisor) {
return bean;
}
if (bean instanceof MethodInterceptor) {
return bean;
}
List<AspectJExpressionPointcutAdvisor> advisors = beanFactory
.getBeansForType(AspectJExpressionPointcutAdvisor.class);
for (AspectJExpressionPointcutAdvisor advisor : advisors) {
if (advisor.getPointcut().getClassFilter().matches(bean.getClass())) {
ProxyFactory advisedSupport = new ProxyFactory();
advisedSupport.setMethodInterceptor((MethodInterceptor) advisor.getAdvice());
advisedSupport.setMethodMatcher(advisor.getPointcut().getMethodMatch());
TargetSource targetSource = new TargetSource(bean, bean.getClass(), bean.getClass().getInterfaces());
advisedSupport.setTargetSource(targetSource);
return advisedSupport.getProxy();
}
}
return bean;
}