Spring Developer Tools Source Analysis: First, file directory monitoring design

Source: Internet
Author: User
Tags comparison diff sleep time interval
Spring Developer Tools Source Analysis

Spring DevTools Introduction
https://blog.csdn.net/isea533/article/details/70495714

Spring Developer Tools, hereafter referred to as devtools, this tool not only useful, but also in the source code of this tool, there are many very learning value of the design, this series will be analyzed Devtools, finally make reading this article readers can not only understand The realization of Devtools can also learn some design ideas of devtools.

The basis of the Devtools feature implementation is to detect code changes, so start with this relatively separate section first. I. File directory monitoring and Design

Starting with JDK 7, Java provides java.nio.file.WatchService for file monitoring, and Commons IO also provides Org.apache.commons.io.monitor.FileAlterationObserver is used to monitor the directory.

Devtools itself to implement a simple file monitoring, through a separate thread, at a certain time interval, the monitoring of the directory to do a snapshot, and then compare the two snapshots before and after the comparison of file information to determine whether the file is new, modified or deleted.

The following diagram is an inter-class diagram of the classes related to file monitoring:

The following are described by class. 1.1 Type enumeration, changing state

In this enumeration class, three states of file changes are defined: Add,modify,delete. 1.2 changedfile, changing documents

This class records the resource directory where the file resides, the file itself, and the state of the file. 1.3 Changedfiles, a collection of change files

This class is a collection of changedfile. Contains all files that change under the same resource directory. 1.4 filesnapshot File Snapshot

Records information about a single file, including whether it exists, the length of the file, and the time it was modified. 1.5 foldersnapshot Directory snapshot

A resource directory takes a directory snapshot, and when the Foldersnapshot is created through the directory, it iterates through all subdirectories, gets all the files inside, and all the specific files correspond to a filesnapshot file snapshot.

The class also provides the following methods:

Public changedfiles getchangedfiles (foldersnapshot snapshot,
            filefilter triggerfilter)

This method can be used to compare two directory snapshots to obtain a diff file, which is the changedfiles in 1.3. The method logic is relatively simple, the first comparison of the two snapshots must be the same directory (the File class equals, as long as the same path is equal), the current instance (this) is an early snapshot, the incoming snapshot is the most recent snapshot, by contrast, if the previous one did not, and the new has, is The new file. The reverse is the deletion , if the two snapshot of the various properties of the different, is modified .

The Triggerfilter (trigger file) In this method is used to implement the function that restarts when the specified file changes.

The first 5 classes are simple classes, and only foldersnapshot contains slightly more complex logic.

Now as long as we can get two different time directory snapshots, we can compare the changed files. 1.6 FileSystemWatcher File system monitoring

This class provides configurable parameters for controlling monitoring cycles, monitoring times, and so on. By default, the number of monitors (Remainingscans) is 1, that is, unlimited number of times, will not stop polling the monitoring directory.

The most important code in this class is the Start method:

/**
 * Start monitoring the source folder for changes.
 */public
void Start () {
    synchronized (this.monitor) {
        saveinitialsnapshots ();
        if (This.watchthread = = null) {
            map<file, foldersnapshot> localfolders = new hashmap<> ();
            Localfolders.putall (this.folders);
            This.watchthread = new Thread (New Watcher (This.remainingscans,
                    new Arraylist<> (this.listeners), This.triggerfilter,
                    this.pollinterval, This.quietperiod, localfolders));
            This.watchThread.setName ("File Watcher");
            This.watchThread.setDaemon (This.daemon);
            This.watchThread.start ();}}}

Here you create a watchthread to perform watcher, tasks, and specific content in the Watcher class below. 1.7 Watcher Monitoring class

The Watcher class is the core of the entire monitoring design, looking first at the main run method:

@Override public
Void Run () {
    int remainingscans = This.remainingScans.get ();
    while (Remainingscans > 0 | | remainingscans = =-1) {
        try {
            if (Remainingscans > 0) {
                This.remainingscans . Decrementandget ();
            }
            Scan ();
        }
        catch (Interruptedexception ex) {
            thread.currentthread (). interrupt ();
        }
        Remainingscans = This.remainingScans.get ();
    }
}

Note the arguments for the previous creation of the worker thread, the Remainingscans default value is-1, in the while judgment here, the value of 1 remains unchanged and the loop is always executed. Then look at the specific scan method:

private void Scan () throws Interruptedexception {
    thread.sleep (this.pollinterval-this.quietperiod);
    Map<file, foldersnapshot> previous;
    Map<file, foldersnapshot> current = This.folders;
    do {
        previous = current;
        Current = Getcurrentsnapshots ();
        Thread.Sleep (This.quietperiod);
    }
    while (Isdifferent (previous, current));
    if (Isdifferent (this.folders, current)) {
        updatesnapshots (current.values ());
    }
}

This method waits 1000-400 milliseconds by default, then calls Getcurrentsnapshots (the result is ordered), waits 400 milliseconds, and if the directory does not change (isdifferent = = False), it will be polled in 400 milliseconds. If the file changes, call the Updatesnapshots method, where there is no complex logic, and it does not dwell on the various methods.

Look again at the Updatesnapshots method:

private void Updatesnapshots (collection<foldersnapshot> snapshots) {Map<File,
    foldersnapshot> updated = new linkedhashmap<> ();
    set<changedfiles> ChangeSet = new linkedhashset<> ();
        for (Foldersnapshot snapshot:snapshots) {foldersnapshot previous = This.folders.get (Snapshot.getfolder ());
        Updated.put (Snapshot.getfolder (), snapshot);
        Changedfiles changedfiles = previous.getchangedfiles (snapshot, This.triggerfilter);
        if (!changedfiles.getfiles (). IsEmpty ()) {Changeset.add (changedfiles);
    }} if (!changeset.isempty ()) {firelisteners (Collections.unmodifiableset (ChangeSet));
} this.folders = Updated; } private void Firelisteners (Set<changedfiles> changeSet) {for (Filechangelistener listener:this.listeners)
    {Listener.onchange (ChangeSet); }
}

This is done by comparing two snapshots of the project directory, finding the difference file, getting set<changedfiles>, and then using the diff file as a parameter to invoke the OnChange listener method. At this point, all registered listener will receive notification of file changes.

Follow us on to see how Devtools uses FileSystemWatcher to monitor the classpath.

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.