Basic Implementation of spring Source Learning Container

Look at spring source depth parsing and record the basic implementation of container in Chapter 2.

Start spring

main method to start spring

public static void main(String[] args) {
//First, you define a bean.xml file, which defines a simple bean tag.
		Resource resource = new ClassPathResource("bean.xml");
		//Instantiate a beanfactory factory to handle some of the instantiations of beans, which is rarely used in actual development.
		BeanFactory factory = new DefaultListableBeanFactory();
		//XmlBean Definition Reader is used to parse the bean.xml file. After parsing xml into elemet s, it is parsed as a parameter in the BeanFactory for parsing.
		BeanDefinitionReader bdr = new XmlBeanDefinitionReader((BeanDefinitionRegistry) factory);
		//Call the method of loading bean s, which really starts to program the properties defined in xml into one java object after another.
		//Look at the process and start from here.
		Student student = factory.getBean("stu", Student.class);
		System.out.printf(". . . . . . " + student);

This line of code starts loading, and when you click in, you go into the loadBean Definitions method of the XmlBean Definition Reader.
This is how the loadBeanDefinitions method works.

	public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
	//This loadBeanDefinitions method calls the overloaded method loadBeanDefinitions, and the parameter passed in is EncodedResource.
		return loadBeanDefinitions(new EncodedResource(resource));

The code for the loadBean Definitions (Encoded Resource encoded Resource) method says this

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
		Assert.notNull(encodedResource, "EncodedResource must not be null");
		if (logger.isTraceEnabled()) {
			logger.trace("Loading XML bean definitions from " + encodedResource);

		Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
		if (currentResources == null) {
			currentResources = new HashSet<>(4);
		if (!currentResources.add(encodedResource)) {
			throw new BeanDefinitionStoreException(
					"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
		try {
		//Convert to inpustStream, which is our usual input stream. After xml is converted to stream, it can be converted to element.
			InputStream inputStream = encodedResource.getResource().getInputStream();
			try {
				InputSource inputSource = new InputSource(inputStream);
				if (encodedResource.getEncoding() != null) {
				//This method is also the conversion of resources, the real operation is the following method.
				return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
			finally {
		. . . . Omit those catch Exceptional code

Return doLoadBean Definitions (inputSource, encodedResource. getResource ()); the method code is as follows

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {

		try {
		//This converts InputSource into Document, and when you see this, you think of xml that we are familiar with, haha.
			Document doc = doLoadDocument(inputSource, resource);
			//After calling the following method, the registration of beans is completed, and the registration of beans is the core of spring.
			int count = registerBeanDefinitions(doc, resource);
			if (logger.isDebugEnabled()) {
				logger.debug("Loaded " + count + " bean definitions from " + resource);
			return count;
		.........Omit those catch Exceptional code.

Int count = registerBean Definitions (doc, resource); the code looks like this

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
//The DefaultBean Definition Document Reader is an object that defines beans and parses various labels of beans. The default implementation here is the DefaultBean Definition Document Reader class, where the createBean Definition Document Reader () method is invoked to instantiate by reflection.
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
		//Get the number of bean s currently defined, and for the first time come in, say 0.
		int countBefore = getRegistry().getBeanDefinitionCount();
		//Here's how to parse bean tags.
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
		//The subtraction of two numbers yields how many bean s are currently defined.
		return getRegistry().getBeanDefinitionCount() - countBefore;

Document Reader. RegiserBean Definitions (doc, createReaderContext (resource); method point in, step by step, you will use the method of doRegisterBean Definitions (Element root).

protected void doRegisterBeanDefinitions(Element root) {
//The following two should be spring's father and son containers. I haven't seen what they mean yet.
		BeanDefinitionParserDelegate parent = this.delegate;
		this.delegate = createDelegate(getReaderContext(), root, parent);
//Default tags to determine whether spring is used or not
		if (this.delegate.isDefaultNamespace(root)) {
		//Resolve the profile tag. The profile tag is what we usually use to define spring's multi-environment.
		//Here the logical judgment is relatively simple, that is to verify it.
			String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
			if (StringUtils.hasText(profileSpec)) {
				String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
						profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
				// We cannot use Profiles.of(...) since profile expressions are not supported
				// in XML config. See SPR-12458 for details.
				if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
					if (logger.isDebugEnabled()) {
						logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
								"] not matching: " + getReaderContext().getResource());
//This method is empty, so it is convenient to continue the secondary development of such people.
		//Resolve bean Tags
		parseBeanDefinitions(root, this.delegate);
		//This method is empty, so it is convenient to continue the secondary development of such people.
		this.delegate = parent;

ParseBean Definitions (root, this. delegate); the code for the method is as follows

	 * Parse the elements at the root level in the document:
	 * "import", "alias", "bean".
	 * @param root the DOM root element of the document
	protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
		if (delegate.isDefaultNamespace(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;
					if (delegate.isDefaultNamespace(ele)) {
					//Parsing and registering BeanDefinitions objects
						parseDefaultElement(ele, delegate);
					else {
						//Resolve custom tags. spring supports custom tags to implement its own business, such as dubbo tags and apollo tags.
		else {
		//Resolve custom tags. spring supports custom tags to implement its own business, such as dubbo tags and apollo tags.

There are many examples of spring's definition and analysis of custom tags on the Internet.
So far spring has finished reading the xml file and converting it into Element. Next, it converts Element into Spring's bean object. The examples in the book are taken as a chapter here.

Tags: Spring xml Dubbo Java

Posted on Mon, 07 Oct 2019 07:31:31 -0400 by explorer