Understand spring principles from source code and implement simple spring framework

Source: Internet
Author: User
Tags event listener

    • Preface (This article is original, reprint please indicate source)

Individuals prior to the framework of learning, will stay in the configuration, use phase. To tell the truth, it will be forgotten after a while. Also do not know the framework of the operating logic, is to know the addition of annotations, it can be used.

Because of internships, time is more, also Thanksgiving met a good teacher, teach and give me time to see the source, although not done much business, but feel more meaningful than doing business. Slowly go with the code, the spring

There is a general solution to the running process. Now share to everyone, the shortcomings, I hope you add, learn from each other.

    • Look at spring from the source

Perhaps we rarely care, classpathxmlapplicationcontext this class, in fact, this class does a lot of things, it is the window that we understand the spring framework.

Classpathxmlapplicationcontext c=new classpathxmlapplicationcontext ("Applicationcontext.xml");

When we execute the above statement,

Public Classpathxmlapplicationcontext (string[] configlocations, Boolean refresh, ApplicationContext parent)
Throws Beansexception {
  Super (parent);
Setconfiglocations (configlocations);
if (refresh) {
Refresh ();
}
}
In fact, this is the constructor, this constructor does two things, one is the setconfiglocations () method initializes some configurations. One is the refresh () function, which is the bean registration, event broadcast, and so on.
Refresh () function is very important, specifically what to do, please see the following source code comments:
public void Refresh () throws Beansexception, IllegalStateException {
Synchronized (this.startupshutdownmonitor) {
Preparerefresh ();
Configurablelistablebeanfactory beanfactory = Obtainfreshbeanfactory ();
Preparebeanfactory (beanfactory);
try {
Allows post-processing of the Bean factory in context subclasses.
Postprocessbeanfactory (beanfactory);
Register the Bean.
Invokebeanfactorypostprocessors (beanfactory);
Registering the processor created by the interception bean
Registerbeanpostprocessors (beanfactory);
Initmessagesource ();
A class that created a broadcast event
Initapplicationeventmulticaster ();
Onrefresh ();
Registering an event listener
Registerlisteners ();
Instantiate those beans that are configured as Singleton
Finishbeanfactoryinitialization (beanfactory);
End refresh, which is actually a broadcast event, etc.
Finishrefresh ();
}
catch (Beansexception ex) {
Destroy already created singletons to avoid dangling resources.
Destroybeans ();
Reset ' active ' flag.
CancelRefresh (ex);
Propagate exception to caller.
Throw ex;
}
}
}
A simple extension of the Spring framework's event mechanism is described in the following ways:
1) event itself (producer)
2) Consumer Event person
3) Event Management (subscription center)
The 1.Spring event itself derives from Applicationevent, and the event consumer is applicationlistener<t extends Applicationevent> Event Management Center for Applicationeventmulticaster
It is responsible for managing listeners and so on.
2.Spring when broadcasting an event, it first looks for the listener for the event, and then goes through the listener calling its onapplicationevent (application Evnet) interface to pass the event to the listener.
Finally when we call Getbean (), actually after the refresh () of the bean registration, has been cached into the map, directly out of the map to take out the instantiation.
    • Easy Code Implementation Spring
     

The above engineering directory structure is the spring annotation class that com.springImpl.annotion put. Com.springImple.core to implement the core classes of the spring framework. Com.springImpl.test put the test class.

1) Note class:

Suppose now that my frame is still relatively rubbing, just one note,

Import java.lang.annotation.*;
@Documented
@Retention (Retentionpolicy.runtime)
@Target (Elementtype.field)//In order to write simple here only for the property that is the domain member variable
Public @interface Resources {
}

2) event class:

Now this event is an agreement, and there is nothing actually

public class Applicationevent {
}

3) Listener Class

Public interface Applicationlistener<t extends applicationevent> {
void Onapplicationevent (T event);
}

4) Event Subscription Center class

Public interface Applicationeventmulticaster {
void Publishevent (Applicationevent event);
}

5) Parsing the configuration file class

    


Import com.springImpl.annotion.Resources;
Import org.w3c.dom.Document;
Import Org.w3c.dom.NamedNodeMap;
Import org.w3c.dom.NodeList;
Import org.xml.sax.SAXException;

Import Javax.xml.parsers.DocumentBuilder;
Import Javax.xml.parsers.DocumentBuilderFactory;
Import javax.xml.parsers.ParserConfigurationException;
Import java.io.*;
Import Java.lang.reflect.Field;
Import Java.util.HashMap;
Import Java.util.Iterator;

public class Configresolver extends Applicationevent implements applicationeventmulticaster{
Private String configxml= "Spring.xml";
Static hashmap<string,object> beanfactory;//here is the imitation beanfactory to save all the beans with the Beanid and corresponding instances in map.
Static hashmap<string,applicationlistener> registrylistener;//here to keep those beans that are listeners
static {
Beanfactory=new hashmap<> ();
Registrylistener=new hashmap<> ();
}
Public configresolver (String config) {
configxml=config==null?configxml:config;//default is Spring.xml
Setconfiglocations (Configxml);
Refresh ();
}
Public Object Getbean (String beanid) {
Return Beanfactory.get (Beanid);
}
private void Setconfiglocations (String configxml) {
Do not do anything, of course, you can do some environmental checks to configure the extraction with a class to deal with, and so I steal a lazy
}
private void Refresh () {
Registering beans
Invokebeanfactorypostprocessors (beanfactory);
Register the Listener
Registerlisteners ();
J Finish flush the surface program has been started can broadcast this refresh complete event broadcast event
Finishrefresh ();
}
private void Finishrefresh () {
Publishevent (this);
}

/**
* Find those beans that are listener types from beanfactory
*/
private void Registerlisteners () {
Iterator<string> It=beanfactory.keyset (). Iterator ();
while (It.hasnext ()) {
String Key=it.next ();
if (Beanfactory.get (key) instanceof Applicationlistener) {
Registrylistener.put (Key, (Applicationlistener) Beanfactory.get (key));
It.remove ();
}
}
}

/**
* All the beans in the configuration file are instantiated into the map
* @param beanfactory
*/
private void Invokebeanfactorypostprocessors (HashMap beanfactory) {

InputStream in= null;
try {
in = ConfigResolver.class.getResourceAsStream (configxml) ==null?
New FileInputStream (Configxml): ConfigResolver.class.getResourceAsStream (Configxml);//compatible resource path and absolute path
} catch (FileNotFoundException e) {
E.printstacktrace ();
}
try {
Documentbuilder db=documentbuilderfactory.newinstance (). Newdocumentbuilder ();
Document Dc=db.parse (in);
NodeList nl=dc.getelementsbytagname ("Bean");
for (int i=0;i<nl.getlength (); i++) {
NamedNodeMap attrs= Nl.item (i). GetAttributes ();
Hashmap<string,string> beanmap=new hashmap<> ();//corresponding to a bean label
for (int j=0;j<attrs.getlength (); j + +) {
String Beanidname=attrs.item (j). Getnodename ();//Pretend this node ID
String Beanid=null;
if (beanidname!=null) {
Beanid = Attrs.item (j). Getnodevalue ();
}
if (beanid!=null) {
Beanmap.put (Beanidname,beanid);
}

String Beanclassname=attrs.item (j). Getnodename ();//Pretend this node is class
String Beanclass=null;
if (beanclassname!=null) {
Beanclass = Attrs.item (j). Getnodevalue ();
}
if (beanclass!=null) {
Beanmap.put (Beanclassname,beanclass);
}
}
String beanid=beanmap.get ("id");
String Beanclass=beanmap.get ("class");
if (beanclass==null| | Beanid==null) {
Continue
}
try {
Class Cls=class.forname (Beanclass);
Object beanobject=cls.newinstance ();
Field[] Fds=beanobject.getclass (). Getdeclaredfields ();
for (Field Fd:fds) {
Fd.setaccessible (TRUE);//get access to private variable permissions
Resources rs=fd.getannotation (Resources.class);
if (rs!=null) {
Fd.set (Beanobject,fd.gettype (). newinstance ());//Instantiate a member with resource annotations
}
}
Beanfactory.put (beanid,beanobject);//put Beans in map
} catch (ClassNotFoundException e) {
E.printstacktrace ();
} catch (Illegalaccessexception e) {
E.printstacktrace ();
} catch (Instantiationexception e) {
E.printstacktrace ();
}
}
} catch (Parserconfigurationexception e) {
E.printstacktrace ();
} catch (Saxexception e) {
E.printstacktrace ();
} catch (IOException e) {
E.printstacktrace ();
}
}

/**
* Broadcast Events
* @param Event
*/
@Override
public void Publishevent (Applicationevent event) {
Iterator<string> It=registrylistener.keyset (). Iterator ();
while (It.hasnext ()) {
Registrylistener.get (It.next ()). Onapplicationevent (event);
}
}
}
6) Look at the test class:
Listener-class listener initiated by listeners
public class Applicationstartlister implements applicationlistener<applicationevent> {
@Override
public void Onapplicationevent (Applicationevent event) {
System.out.println ("Springimpl App start");
}
}
  
Let's say there's a blind man who injected an eye with a note. Ege Class
public class Blind {
@Resources
Private Ege Ege;
Public Ege Getege () {
return Ege;
}
}
Eye Ege Class
public class Ege {
Public String See () {
Return "The world was so beautiful.";
}
}

Main program
 public class DoMain {
  public static void Main (String []args) {
Configresolver cfg=new configresolver ("E:\\__java\\__idea_proj\\springimpl\\src\\resources\\spring.xml");
Blind b= (Blind) Cfg.getbean ("Mybean");
System.out.println ("Tell me how are the world:" +b.getege ().)
}
}
Configuration file

7) Running Results

      

After that, a simple imitation of the spring framework is complete.







Understand spring principles from source code and implement simple spring framework

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.