package spring;
import cn.hutool.core.util.ArrayUtil;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.env.AbstractEnvironment;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* @author mawt
* @description
* @date 2020/9/14
*/
public class MyApplicationContext extends ClassPathXmlApplicationContext {
private static class MyDefaultBeanDefinitionDocumentReader extends DefaultBeanDefinitionDocumentReader {
@Override
protected void preProcessXml(Element root) {
System.out.println("处理配置文件前...");
NodeList nodeList = root.getChildNodes();
int length = nodeList.getLength();
for (int i = 0; i < length; i++) {
Node item = nodeList.item(i);
NamedNodeMap attributes = item.getAttributes();
if (attributes == null) continue;
for (int j = 0; j < attributes.getLength(); j++) {
Node beanNode = attributes.item(j);
System.out.println("name=" + beanNode.getNodeName() + ",value=" + beanNode.getNodeValue());
}
}
}
@Override
protected void postProcessXml(Element root) {
System.out.println("处理配置文件后...");
}
}
public MyApplicationContext(String... configLocation) throws BeansException {
super(configLocation);
}
@Override
protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
super.initBeanDefinitionReader(reader);
reader.setDocumentReaderClass(MyDefaultBeanDefinitionDocumentReader.class);
}
public static void main(String[] args) {
//-Dspring.profiles.active=dev
System.setProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, "pro");
MyApplicationContext ctx = new MyApplicationContext("classpath:application.xml");
String[] aliases = ctx.getAliases("user");
System.out.println(ArrayUtil.join(aliases, ","));
}
}
源码:
AbstractApplicationContext.refresh()
// Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
@Override protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); customizeBeanFactory(beanFactory); loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
@Override protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { // Create a new XmlBeanDefinitionReader for the given BeanFactory. XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); // Configure the bean definition reader with this context's // resource loading environment. beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); // Allow a subclass to provide custom initialization of the reader, // then proceed with actually loading the bean definitions. initBeanDefinitionReader(beanDefinitionReader); //继承ctx后重写该方法 loadBeanDefinitions(beanDefinitionReader); }