I. Overview of SPRINGIOC containers
IOC container and dependency reversal mode
In object-oriented systems, objects encapsulate data and process data, and the dependencies of objects are often reflected in the dependence on data and methods. These dependencies can be done by giving the object's dependency injection to the framework IOC container. He can decouple the code and improve the testability of the code.
The implementation of dependency control inversion is implemented in many ways, in spring, the IOC container is the carrier that implements this pattern, he can inject the data directly into the object when the object is generated or initialized, or it can inject the dependency on the method call by injecting the object reference into the object data domain. This dependency injection can be recursive, and the object is entered on a level-by-layer basis. Simplifying the management of object dependencies simplifies the complexity of object-oriented systems to a great extent.
On how to reverse the control of dependency, transfer control from the specific business object to the platform or framework. is an effective and feasible solution to reduce the complexity of object-oriented system design and improve the testability of object-oriented system.
After applying control inversion, when the object is created, a reference to the object to which it is dependent is passed to the external entity of all objects within the control system, that is, the dependency is injected into the object. So, control inversion is about how an object obtains a reference to the object he relies on, where inversion refers to the reversal of responsibility.
By using the IOC container, the management of the object's dependencies is reversed, to the IOC container, and the interdependence between objects is managed by the IOC container and the object is injected by the IOC container. Simply put, because the establishment and maintenance of many object dependencies does not need to be strongly correlated with the state of the system, it is possible to implement operations such as creating new objects, assigning values to object references in object-oriented programming, and then handing them over to the container. With this dependency, the same parts of the functionality scattered in different code are concentrated as part of the container, which is part of the infrastructure of the object-oriented system.
The interdependencies between objects are also relatively stable, and generally do not change with the application's operational state, which makes these objects very suitable for IOC containers to manage, although they exist in the application system, but the application system does not assume responsibility for managing these objects, but rather by relying on reversals to give the responsibility to the container. With these backgrounds in view, the principles of the Spring IOC container are not difficult to understand. In the concrete implementation of the principle, spring has its own unique ideas, the implementation of skills and rich product characteristics.
SPRINGIOC's application scenario
In Java EE Enterprise Application Development, the IOC design pattern is a powerful tool for decoupling the complex relationships between components, and the Spring IOC module is an implementation of this pattern.
From the point of view of basic services, Spring provides services that are not very different from the services provided by the EJB container, but the design differs greatly in the way in which the services are obtained: In spring, Spring IOC provides a basic JavaBean container, Managing dependencies through the IOC pattern and enhancing the basic functions of Pojo objects such as JavaBean, such as transaction management, lifecycle management through dependency injection and AOP facets, and for EJBs, a simple EJB component requires writing a remote/local interface, The home interface and the bean's implementation class, and the EJB runtime cannot be detached from the EJB container, and finding other EJB components also needs to be done in such a way as jndi, resulting in a dependency on the EJB container and technical specifications. That is to say, Spring restores EJB components to Pojo objects or JavaBean objects, which reduces the reliance of application development on traditional Java EE specifications.
By using the IOC container, you can reverse the direction of resource acquisition, let the IOC container proactively manage these dependencies, inject these dependencies into the components, and make these dependencies more flexible to adapt and manage. In a specific implementation, interface injection (Type 1 IOC), Setter injection (Type 2 IOC), constructor injection (Type 3 IOC) is the primary injection method. Setter injection and constructor injection are the main approaches in spring's IOC design, and in contrast, setter injection is a common injection method when using spring, and in order to prevent injection exceptions, the SPRINGIOC container also provides checks for specific dependencies.
Ii. Design and implementation of the IOC container series: Beanfactory and ApplicationContext
In the design of the SPRINGIOC container, there are two main container series, one is the simple container series that realizes the Beanfactory interface, this series container only realizes the basic function of the container, the other is the ApplicationContext application context, He exists as a high-level form of container. The application context adds many framework-oriented features on the basis of simple containers, and also makes many adaptations to the application environment. The following is a brief analysis of the design and implementation of the SPRINGIOC container.
Spring's IOC container series
In fact, for the users of the IOC container, the beanfactory and applicationcontext that we often touch can be seen as concrete representations of the container. If deep into the implementation of spring, actually represents a series of different functions of the container products, knowledge container function size has its own characteristics.
As with the product specification, as in the case of goods, as an IOC container, it is also necessary to specify the basic functional specification for his implementation, which is designed as an interface class Beanfactory, which embodies the most basic functional specification that spring sets for providing the user with the IOC container. As an example of a bucket sold by a department store, if the IOC container is seen as a bucket, the beanfactory defines the basic functions that can be used as buckets, such as at least water, a handle, etc.
design of Spring IOC container
We have already learned the overview of the IOC container series. In spring, how is this IOC container designed? Let's look at the interface design for the IOC container:
three sets of interface system:
1, from the interface Beanfactory Road Hierarchicalbeanfactory, and then to Configurablebeanfactory, is a major beanfactory design path
2, the interface design with the ApplicationContext application context interface as the core
3, with Beanfactory and ApplicationContext as the core.
1. Beanfactory Application Scenario
Beanfactory provides the functionality of the most basic IOC container, and the definition of these functions can be seen in the interface beanfactory.
In spring's code implementation, Beanfactory is just an interface class, and does not give a concrete implementation of the container, and we see Defaultlistablebeanfactory, Xmlbeanfactory, ApplicationContext and so on can be seen as a container, such as the specific implementation of a function, that is, the container system of the specific container products. Let's look at how Beanfactory defines the basic interface of the IOC container.
When a user uses a container, the escape character "&" can be used to obtain the Factorybean itself, which distinguishes the object from the container to obtain Factorybean and acquires the Factorybean itself. For example, if
Myjndiobject is a factorybean, then using &myjndiobject to get the Factorybean, instead of Myjndiobject this Factorybean produced objects.
The Beanfactory interface designs the Getbean method, which is the primary method for using the IOC container API, which allows the acquisition of Bean,bean managed in the container to be indexed by a specified name. If the bean's type needs to be checked when the bean is acquired, the Beanfactory interface defines the Getbean method with parameters, which, unlike the Getbean method type without parameters, increases the requirements for the type of bean retrieval.
The user can use the bean name through the Getbean in the Beanfactory interface method, so that when the bean is acquired, if the bean to be obtained is of type prototype, The user can also generate a corresponding parameter for the specified constructor for the bean of this prototype type. With the beanfactory definition, the user can do the following:
- The interface method Containsbean allows the user to determine whether the container contains a bean with the specified name
- The Issingleton class query by interface method is whether the bean of the specified name is a bean of type Singleton. For the Singleton property, the user can be specified again in beandefinition.
- The interface method Istypematch is used to query whether the class type of the bean with the specified name is a specific class type.
- Query the class type of the bean with the specified name through the interface method gettype
- all aliases of the bean with the name specified by the interface method getaliases class query
2, the design principle of the Beanfactory container
The Beanfactory interface provides specifications for using the IOC container. We take the implementation of Xmlbeanfactory as an example to illustrate the design principle of IOC container. The
can see that the xmlbeanfactory of a simple IOC container family provides only the most basic functions of the IOC container. If you want to extend the product of your own container, we need to see if spring has provided a thread or a similar container implementation for our reference.
Carefully read Xmlbeanfactory's source code, Xmlbeanfactory inherits from the Defaultlistablebeanfactory class, he actually contains the basic IOC container has important functions, It is also a basic product in a series of containers that will be used in many places. In spring, the fact is that defaultlistablebeanfactory is used as a default full-featured IOC container, and Xmlbeanfactory has added new features to the inheritance. He is an XML-related beanfactory, which means that he is an IOC container that can read beandefinition defined in an XML file.
How do these implementations of XML read function? The processing of XML file definition information is not done directly by Xmlbeanfactory. In Xmlbeanfactory, a Xmlbeandefinitionreader object is initialized with this reader object, The XML-defined beandefinition has a place to deal with it. As we can see, the processing of these XML forms is actually done by Xmlbeandefinitionreader . When constructing the IOC container, the
constructs a beandefinition source of information that needs to be encapsulated into the resource class in spring xmlbeanfactory. Resource is the class that spring uses to encapsulate I/O operations. For example:
new ClassPathResources("beans.xml");
Such concrete classpathresource to construct the required resource, and then pass resource as a construction parameter to the Xmlbeanfactory constructor. This allows the IOC container to conveniently locate the required beandefinition information to complete the container initialization and dependency injection process for the bean.
below to see the xmlbeanfactory Source:
/** * Convenience extension of {@linkDefaultlistablebeanfactory} that reads beans definitions * from an XML document. Delegates to {@linkXmlbeandefinitionreader} underneath; Effectively * equivalent to using a xmlbeandefinitionreader with a defaultlistablebeanfactory. * * <p>the structure, element and attribute names of the required XML document * is hard-coded in this class. (Of course a transform could is run if necessary * to produce this format). "Beans" doesn ' t need to be the root element of the XML * Document:this class would parse all bean definition elements in t He XML file. * * <p>this class registers each bean definition with the {@linkDefaultlistablebeanfactory} * Superclass, and relies on the latter ' s implementation of the {@linkBeanfactory} interface. * It supports singletons, prototypes, and references to either of these of beans. * See {@code"Spring-beans-3.x.xsd"} (or Historically, {@code"Spring-beans-2.0.dtd"}) for * Details on options and configuration style. * * <p><b>for advanced needs, consider using a {@linkDefaultlistablebeanfactory} with * an {@linkXmlbeandefinitionreader}.</b> the latter allows for reading from multiple XML * Resources and is highly configurable In its actual XML parsing behavior. * *@authorRod Johnson *@authorJuergen Hoeller *@authorChris Beams *@sinceApril 2001 *@seeOrg.springframework.beans.factory.support.DefaultListableBeanFactory *@seeXmlbeandefinitionreader *@deprecatedAs of Spring 3.1 in favor of {@linkDefaultlistablebeanfactory} and * {@linkXmlbeandefinitionreader} */@Deprecated@SuppressWarnings({"Serial","All"}) Public class xmlbeanfactory extends defaultlistablebeanfactory { Private FinalXmlbeandefinitionreader reader =NewXmlbeandefinitionreader ( This);/** * Create a new xmlbeanfactory with the given resource, * which must is parsable using DOM. * @param resource XML resource to load beans definitions from * @throws beansexception in case Loading or parsing errors * /Public xmlbeanfactory (Resource Resource)throwsbeansexception { This(Resource,NULL); }/** * Create a new xmlbeanfactory with the given input stream, * which must is parsable using DOM. * @param resource XML resource to load beans definitions from * @param parentbeanfactory Parent Bean Factory * @throws beansexception in case of loading or parsing errors * *Public Xmlbeanfactory (Resource Resource, Beanfactory parentbeanfactory)throwsbeansexception {Super(parentbeanfactory); This. Reader.loadbeandefinitions (Resource); }}
Other IOC containers, such as ApplicationContext, implement the same basic principles as xmlbeanfactory, by holding or extending defaultlistablebeanfactory to obtain basic IOC container functionality.
Referring to the implementation of xmlbeanfactory, we use defaultlistablebeanfactory programmatically, from which we can see some basic processes used by the IOC container. For example:
new ClassPathResource("beans.xml"newnew XmlBeanDeifinitionReader(factory);reader.loadBeanDefinition(res);
This allows us to use the defaultlistablebeanfactory as an IOC container through the factory object. The steps are as follows:
- Create an abstract resource for the IOC configuration file that contains the definition information for the beandefinition.
- Create a beanfactory, where you use Defaultlistablebeanfactory
- The
- creates a reader that loads beandefinition, where xmlbeandefinitionreader is used to load beandefinition in the form of an XML file, configured to Beanfactory by a callback
- The
- reads configuration information from a defined resource location, and the specific parsing process is done by the Xmlbeandefinitionreader class.
3, applicationcontext application Scenarios
in spring, the system has provided users with a number of well-defined container implementations, without the need for us to hands. In addition to being able to provide the basic functionality of the container described earlier, the applicationcontext commonly used by developers has not provided the following additional services. So ApplicationContext is an IOC container of advanced morphological significance, and he adds many additional functions on beanfactory basis. The
supports different sources of information, and we can see that ApplicationContext extends the Messagesource interface to support internationalization
access to resources. In support of Resourceloader and resource, we can get bean definition resources from different places
Support application events, inherit interface Applicationevenpublisher, and introduce event mechanism in context. The life cycle of events and beans is combined to facilitate the management of beans
provides additional services in ApplicationContext. Make the IOC container more versatile, frame-oriented usage style.
4, the design principle of the ApplicationContext container
in the ApplicationContext container, We take the implementation of Filesystemxmlapplicationcontext as an example
in the design of Filesystemxmlapplicationcontext, We see that the main functionality of the ApplicationContext application context has been implemented in the Filesystemxmlapplicationcontext base class Abstractxmlapplicationcontext, In Filesystemxmlapplicationcontext, as a specific application context, you only need to implement two functions related to his or her own design.
A feature is the process of initializing the IOC container's refresh while using Filesystemxmlapplicationcontext directly for instantiating support for this application context, The Filesystemxmlapplicationcontext source code is as follows:
/** * Create a new filesystemxmlapplicationcontext with the given parent, * loading the definitions from the G Iven XML files. * @param configlocations array of file paths * @param Refresh whether to automatically refresh the C Ontext, * Loading all beans definitions and creating all singletons. * Alternatively, call refresh manually after further configuring the context. * @param Parent The parent context * @throws beansexception If context creation failed * @se E #refresh () */ Public Filesystemxmlapplicationcontext(string[] Configlocations,BooleanRefresh, ApplicationContext parent)throwsbeansexception {Super(parent); Setconfiglocations (configlocations);if(refresh) {Refresh (); } }
This refresh process involves some of the column complex operations initiated by the IOC container, and these operations are similar for different container implementations, so they are encapsulated in the base class. So, what we see in the Filesystemxml design is just a simple call.
Another feature is the Filesystemxmlapplicationcontext design-specific feature, which is related to the Bean definition resource for how to load XML from the file system. This process allows the file system to read beandefinition in XML form, because different application context implementations correspond to different ways of reading beandefinition, The implementation code in Filesystemxmlapplicationcontext is as follows:
/** * Resolve resource paths as file system paths. * <p>note:even If a given path starts with a slash, it'll get * interpreted as relative to the current VM wor King directory. * This was consistent with the semantics in a Servlet container. * @param path to the resource * @return Resource handle * @see org.springframework . Web.context.support.xmlwebapplicationcontext#getresourcebypath * / @Override protectedResourceGetresourcebypath(String Path) {if(Path! =NULL&& Path.startswith ("/") {Path = Path.substring (1); }return NewFilesystemresource (path);
You can see that this method is called to get the Filesystemresource resource location.
To be Continued ...
Spring Technology Insider--spring Framework's IOC container implementation (i)