The basic structure of the spring framework parsing Java _java

Source: Internet
Author: User
Tags event listener object object prepare

In the Java session, a bull named Rod Johnson found that the initial Java enterprise-level development was in a state of chaos.

As a result, it is determined to write a common infrastructure that solves the problem.

Because it is convinced that interface-oriented programming can control change to the minimum, but also conducive to expansion and change. As a result, it writes the following interface.

In the chaotic state, the first thing to create is the mother beanfactory of all objects, and with it, we can get all the objects and attributes it breeds, that is to say, first of all, Gaia-the mother of the Earth.

With the original mother, Beanfactory,johnson, if I were to get a set of bean objects, not just one or a few? In addition, what if the mother's child should also be pregnant with the object? As a result, Johnson created Listablebeanfactory to manipulate a set of bean objects, such as Getbeansoftype, to get a group of beans of the same type Create hierarchicalbeanfactory to solve multiple beanfactory problems, such as getparentbeanfactory can get Beanfactory's father factory.

This beanfactory is ultimately to be used in an application, and it is necessary to give beanfactory the ability to move in an application. In Beanfactory, you only need to consider the behavior associated with the bean, such as how to get the type of Bean,bean, and if you want to give it in the application of the ability to consider more, such as the application of the name, start time, ID, etc. with the application itself related to the behavior and attributes, So Johnson thought of creating ApplicationContext. Johnson thought, this applicationcontext must be able to do a lot of things, to be able to handle parameterized and internationalized text information, so added the Messagesource interface; to be able to release events to decouple components, So there is the Applicationeventpublisher interface, the resource file, the Resourcepatternresolver interface, and the ability to handle objects in different environments, So there is the Environmentcapable interface.

ApplicationContext inherits all of these interfaces.

But most importantly, whether it's beanfactory or applicationcontext, they all need to have configurable capabilities, So there are sub-interface configurablebeanfactory and Configurableapplicationcontext, and the web is a very important trend at the time, and it's a little bit more unique than other applications. Need to get servletcontext, so have webapplicationcontext.

So far, Johnson has been an abstract reflection of interface-oriented behavior and has not specifically implemented them.

Looking at the creation of Beanfactory and Applicationcontext,johnson realized that the day's work was far from over, because it didn't really solve how to get the whole system working, Johnson began to think about how to achieve them.

Johoson first thought of is this realization should have what ability? Of course, the Autowirecapablebeanfactory,listablebeanfactory and Configurablebeanfactory mentioned earlier should be included. Thus created the configurablelistablebeanfactory. Second, you need to consider several capabilities for the Bean object, one is the ability to alias, the other is the ability to save a single instance object, and the third is the ability to cache; they were in the Simplealiasregistry class, The Defaultsingletonbeanregistry class and the Factorybeanregistrysupport class are implemented.

In the end, it created the Defaultlistablebeanfactory, the prototype of all the IOC plants in spring, the first real child of Beanfactory, the child is very important, and has become the basis for independent creation of the IOC container, if there is expansion and use , most of them inherit it or use it in combination.

If you want to initialize a defaultlistablebeanfactory, you can use the following code

Classpathresource res = new Classpathresource ("Applicationcontext.xml"); 
    Defaultlistablebeanfactory f = new defaultlistablebeanfactory (); 
    Xmlbeandefinitionreader r = new Xmlbeandefinitionreader (f); 
    R.loadbeandefinitions (RES); 

  Next Johnson thought, Beanfactory has a more comprehensive default implementation, so what about ApplicationContext? So Johnson tirelessly created 3 important ApplicationContext implementations: Filesystemxmlapplicationcontext, Classpathxmlapplicationcontext, Annotationconfigwebapplicationcontext (In fact, there are many, such as processing portlets, processing the web)

Johnson first considered how to do the spring initiation process, which should be placed at a more abstract level so that all classes in the lower class could be reused. So he realized the configurableapplicationcontext with a abstractapplicationcontext. Another important function is to load a file in the form of a resource, which requires abstracting the resource into the resource class, abstracting the concrete implementation of the targeted resource to Resourceloader, Abstractapplicationcontext also needs to inherit Defaultresourceloader to provide this functionality. Abstractapplicationcontext completed the entire initiation process (God arranged it to be completed the following day), but did not manage the beanfactory. So, its subclass Abstractrefreshableapplicationcontext did this thing specifically, realized Refreshbeanfactory, Closebeanfactory, Getbeanfactory specifically manages the lifecycle of the beanfactory, but Abstractrefreshableapplicationcontext still does not load all the configured beans. Where to load the configured resources, actually to the lower classes to do, such as Filesystemxmlapplicationcontext, is to the file system to read an XML form of the ApplicationContext Classpathxmlapplicationcontext to the class loading path to read the ApplicationContext. Annotationconfigwebapplicationcontext then loads the bean,spring scan from the annotation of the class file and begins.

Looking at the main frame that had been built up, Johnson smiled with satisfaction and fell asleep.

On the first day, Johnson completed a spring's overall framework.

The next day, Johnson was ready to actually deal with the problems left in front. For example, Spring's container initialization process. As pictured, Johnson divides this process into a number of sub processes that revolve around how to load beans into this ambitious goal.

This process is placed in the Refresh method in the Abstractapplicationcontext. The code is as follows: Johnson divides the process of the refresh into many subroutines, and the subroutines are at the same level of abstraction, which is intended to give posterity an example.

public void Refresh () throws Beansexception, IllegalStateException {synchronized (this.startupshutdownmonitor) { 
    Prepare this context for refreshing. 
 
    Preparerefresh (); 
    Tell the subclass to refresh the internal bean factory. 
 
    Configurablelistablebeanfactory beanfactory = Obtainfreshbeanfactory (); 
    Prepare The Bean Factory for the 
 
    Preparebeanfactory (beanfactory); 
      try {//allows post-processing of the Bean factory in context subclasses. 
 
      Postprocessbeanfactory (beanfactory); 
      Invoke factory processors registered as beans in the context. 
 
      Invokebeanfactorypostprocessors (beanfactory); 
      Register Bean processors that intercept bean creation. 
 
      Registerbeanpostprocessors (beanfactory); 
      The Initialize message source is for the context. 
 
      Initmessagesource (); 
      Initialize Event Multicaster for the this context. 
 
      Initapplicationeventmulticaster (); INitialize other special beans in the specific context subclasses. 
 
      Onrefresh (); 
      Check for listener beans and register them. 
 
      Registerlisteners (); 
      Instantiate all remaining (Non-lazy-init) singletons. 
 
      Finishbeanfactoryinitialization (beanfactory); 
      Last Step:publish corresponding event. 
    Finishrefresh (); 
      The catch (Beansexception ex) {//Destroy already created singletons to avoid dangling. 
 
      Destroybeans (); 
      Reset ' active ' flag. 
 
      CancelRefresh (ex); 
      Propagate exception to caller. 
    Throw ex; 
 } 
  } 
}

If you look at a higher level, actually these processes revolve around several aspects: 1. The life cycle of the refresh; 2. Initialization and preparation of the beanfactory; 3. Build and register beandefinition;4. Beanfactory after processor 5. Set up messages, events, and listeners.
1. Refresh Life cycle

Preparerefresh, this process mainly logs that spring is started, initializes the property resource (such as the initialization of some resources in Serlvet), and verifies the property resource (for example, only the key is written without value).

Onrefresh, the goal is to provide some special applicationcontext, so that they have the ability to be able to expand during the refresh process. Most of the current uses are for servlet application context settings theme

Finishrefresh, do some finishing work, such as initializing lifecycleprocessor, releasing the events at the end of the refresh, and so on.

CancelRefresh, the main is to change the current state to non active when the exception is generated.

2. Initialization and preparation of the Beanfactory

Johnson thought we should let beanfactory load and register the bean transparently when it was initialized, so that my encapsulation was very successful for the outside world, so this step actually does a lot of things. The following illustration omits a number of steps and lists only the key points.

Abstractapplicationcontext will call Refreshbeanfactory, which will first check and close the existing beanfactory, and then create a new beanfactory, Then use the factory to load all beandefinition

Among them, Loadbeandefinitions will give subclasses to do different implementations, such as Abstractxmlapplicationcontext is mainly read through XML ; The Annotationconfigwebapplicationcontext implementation calls the scanner to scan the bean in the class

3. Generate and register Beandefinition
After parsing the XML configuration, the Defaultbeandefinitiondocumentreader Parsedefaultelement method is processed according to the elements in the XML. Where the bean element is encountered, the Registerbeandefinition method in Beandefinitionreaderutils is eventually invoked, and the method passes in a parameter of beandefinitionregistry. is actually a callback to the Defaultlistablebeanfactory Registerbeandefinition method to register the Beandefinition ( Defaultlistablebeanfactory implemented the Beandefinitionregistry).

4. Beanfactory Post processor

The Beanfactory processor is a way that spring provides to make its subclasses flexible and extensible. Spring is divided into 2 steps: postprocessbeanfactory,invokebeanfactorypostprocessors. Registerbeanpostprocessors is instantiated and calls all beanpostprocessor to extend the bean before and after the bean is initialized.

5. Set up messages, events, and listeners

Set the default message source for Delegatingmessagesource, such as the factory has messagesource to use the Messagesource, event multicast for Simpleapplicationeventmulticaster, If there are already applicationeventmulticaster in the factory, use the Applicationeventmulticaster and register all the applications listener so that they can receive events

Message Source: Messagesource is an important way to internationalize resource files, and spring supports the message source in ApplicationContext.

Spring provides a default implementation of Messagesource, using Java.util.ResourceBundle to extract messages. Spring can access the message directly from Applicationcontext.getmessage () by configuring a Messagesource bean with a special ID and developing a i18n file name. If you are in JSP, you can also access the message by Spring:message this tag.

Event: Event is a more important decoupling mechanism, spring is introduced in the core ApplicationContext, its principle is relatively simple, on the one hand is the event generation side, can send event, on the other hand it seems that the event listener can respond to the event. And the implementation is basically in the production side hold live an event listener collection, and all listeners "register" (that is, join) to this event listener collection.

In spring, ApplicationContext is used as the event creator, using Applicationlisteners as a listener collection and Applicationeventmulticaster for event publishing.

Several steps for event Publishing:

Subscribe: Initially Addapplicationlistener will add Applicationlistener to the Listener collection.

Release: ApplicationContext inherited the Applicationeventpublisher, thus realizing the publishevent, The method first iterates through the Applicationlisteners collection of this applicationcontext and calls onapplicationevent for each listener, so each listener is notified to the This step completes the same event release for all Applicationlisteners of ApplicationContext's parent.

Event publishing is very common, not only our own applications can use this event release, the spring framework itself is also using event publishing. The following are the applications of events in spring:

The Finishrefresh will post a contextrefreshedevent indicating that the refresh is terminated by this notification listener. In ApplicationContext, the start and stop methods publish events that indicate the start or end of the context.
Having created the spring's main framework and the running process, Johnson discovered that spring offers many flexible extensions. So Johnson is going to announce the use of these flexible extensions on the third day.

1. Beanpostprocessor. Beanpostprocessor provides the extension interface after the Bean is created, and beanpostprocessor is the preferred method when you need to handle the bean after it has been created.

2. Aware. The injected bean needs to understand some parts of its container, and spring completes the callback by aware, such as beannameaware, to let the Bean know its name, Beanfactoryaware can let the bean know beanfactory, Applicationcontextaware, you can let the bean manipulate applicationcontext. In this way, the bean injected into spring can do a broader thing.

  for beanpostprocessor extensions, Spring has an example of how to identify aware beans. The Aware bean is a special bean that requires spring to inject some extra attributes into it, so what does the injected process spring do? In fact, Spring did not write him in the core process, but instead put it in the Applicationcontextawareprocessor this beanpostprocessor, The postprocessbeforeinitialization final invokeawareinterfaces of the beanpostprocessor is used to determine the type of the bean and inject the corresponding property. This approach utilizes the Beanpostprocessor to complete another extended usage, which is superb.

private void Invokeawareinterfaces (Object bean) {if (bean instanceof Aware) {if (Bean instanceof environmen 
      Taware) {(environmentaware) bean). Setenvironment (This.applicationContext.getEnvironment ()); } if (bean instanceof Embeddedvalueresolveraware) {(embeddedvalueresolveraware) bean). Setembeddedvaluere 
      Solver (New Embeddedvalueresolver (This.applicationContext.getBeanFactory ())); } if (bean instanceof Resourceloaderaware) {(resourceloaderaware) bean). Setresourceloader (This.applicati 
      Oncontext); } if (bean instanceof Applicationeventpublisheraware) {(applicationeventpublisheraware) bean). Setapplica 
      Tioneventpublisher (This.applicationcontext); } if (bean instanceof Messagesourceaware) {(messagesourceaware) bean). Setmessagesource (This.applicationc 
      Ontext); } if (bean instanceof Applicationcontextaware) {(applicationcontextaware) Bean). Setapplicationcontext (This.applicationcontext); 
 } 
    } 
  }

There are more uses for aware, such as the following code to sense that applicationcontext,spring will inject applicationcontext after the bean is created, so we can use that context to complete the event release.

public class Hellobean implements Applicationcontextaware {  
  
  private applicationcontext applicationcontext;  
  Private String Helloword = "hello! world! ";  
  
  public void Setapplicationcontext (ApplicationContext context) {  
    This.applicationcontext = context;  
  }  
  
  public void Sethelloword (String helloword) {  
    This.helloword = Helloword;  
  }  
  
  Public String Gethelloword () {  
    applicationcontext.publishevent (  
        new Propertygettedevent ("[+ Helloword +]" is getted "));  
    Return Helloword  
  }  
}  

3. Beanfactorypostprocessor, this postprocessor is usually used to process the extended interface after the beanfactory is created. As an example, after the bean is injected, it will be created in beanfactory to automatically print the number of beans injected:

The public class Beancounter implements beanfactorypostprocessor{@Override the public 
  void Postprocessbeanfactory ( Configurablelistablebeanfactory beanfactory) 
      throws beansexception { 
    System.out.println ( Beanfactory.getbeandefinitioncount ()); 
  } 
   
 

4. Factorybean. Factorybean is a special kind of bean that allows you to inject into the spring container and generate a real bean, so you can define that Factorybean itself is a bean that has the ability to provide beans. Here's how spring uses this bean, starting with the call from Factorybean.
To distinguish between ordinary beans and factorybean,spring, there must also be a process of judging them and dealing with them, which is in the getobjectforbeaninstance of Abstractbeanfactory.

Protected object Getobjectforbeaninstance (object beaninstance, string name, String beanname, Rootbeandefinition m 
    BD) {//Don ' t let calling code try to dereference the factory if the bean isn ' t a factory. if (beanfactoryutils.isfactorydereference (name) &&! ( Beaninstance instanceof Factorybean)) {throw new Beanisnotafactoryexception (Transformedbeanname (name), BeanInstanc 
    E.getclass ()); 
    //Now we have the bean instance, which is a normal bean or a factorybean.  If it ' s a factorybean, we use it to create a bean instance, unless the//caller actually wants a reference to the 
    Factory. if (!) ( Beaninstance instanceof Factorybean) | | 
    Beanfactoryutils.isfactorydereference (name)) {return beaninstance; 
    The Object object = null; 
    if (mbd = = null) {object = Getcachedobjectforfactorybean (Beanname); 
      } if (object = = null) {//return bean instance from factory. factorybean<?&Gt 
      Factory = (factorybean<?>) beaninstance; 
      Caches object obtained from Factorybean if it is a singleton. 
      if (mbd = = null && containsbeandefinition (beanname)) {mbd = Getmergedlocalbeandefinition (beanname); 
      Boolean synthetic = (mbd!= null && mbd.issynthetic ()); 
    Object = Getobjectfromfactorybean (Factory, Beanname,!synthetic); 
  return object; 
 }

As you can see, if it is a normal bean, it is returned directly, and if it is Factorybean, the final call calls Factory.getobject to return the concrete object. If you take the whole spring as an abstract factory and produce abstract beans, then Factorybean is the specific factory that produces the objects you need.
There are a lot of factorybean usages in spring, and for a more common example, the integration of Hibernate sessionfactory is typically injected into Localsessionfactorybean, But this sessionfactory is actually not a normal bean, it can be produced simply by injecting it into a configuration file, it has a lot of custom parts, so spring makes the bean a Factorybean and controls the objects it produces.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.