From today onwards, step by step into the path of source analysis. At first, we must start from the simple. Let's start with the most powerful framework in Java history,--spring 、、、 Resources Abstraction Interface resource.
I read a lot of analysis spring source, often at the beginning is Spring IOC, AOP, beanfactory such a spring typical module, really tired, these leave to later. My idea is that analysis is an analysis of other people have not analyzed, or in different ways to analyze the analysis of others.
There may be many years of use of spring programmers have limited knowledge of resource, after all, access to resources is generally the time to build a Web engineering framework. But it's also very good to know about it.
The purpose of this interface is to make it easier for us to manipulate the underlying resources. Because the JDK manipulates the underlying resources basically is Java.net.URL, Java.io.File, java.util.Properties these. The resource fetch is basically based on the absolute path or the relative path of the current class. It is also inconvenient to obtain resources from the context of a classpath or Web container. The resource interface provides a more powerful ability to access the underlying resources.
Needless to say, look at the source code before looking at the resource class structure.
First, class structure
First, Resource interface
, the Resouce interface is not a root interface, it inherits a simple parent interface Inputstreamsource, which has only one method to return an input stream:
throws IOException;
To, directly on the resource interface source code, Chinese is I according to the English annotation own translation, as follows:
Public InterfaceResourceextendsInputstreamsource {BooleanExists ();//whether the resource exists BooleanIsReadable ();//whether the resource is readable BooleanIsOpen ();//whether the handle represented by the resource is opened by a streamURL GetURL ()throwsIOException;//returns a handle to the URL of a resourceURI GetURI ()throwsIOException;//returns a handle to the URI of the resourceFile getFile ()throwsIOException;//returns a handle to a resource's file LongContentLength ()throwsIOException;//length of resource content LongLastModified ()throwsIOException;//last modification time of the resourceResource createrelative (String relativepath)throwsIOException;//Create a new resource based on the relative path of the resourceString GetFileName (); //the file name of the resourceString getdescription (); //description of the resource}
This is nothing to say, go on!
Second, abstract class Abstractresource
For any interface, this direct abstract class is a heavy priority, which condenses most of the public implementations of the interface. Translated as follows:
Public Abstract classAbstractresourceImplementsResource { Public BooleanExists () {//determine if the file exists, if the judgment process is abnormal (because it calls SecurityManager to judge), the corresponding stream is closed. Try { returnGetFile (). exists (); } Catch(IOException ex) {Try{InputStream is= getInputStream ();//the getInputStream () method overrides the quilt class,Is.close (); return true; } Catch(Throwable isex) {return false; } } } Public BooleanIsReadable () {//directly returns true, readable return true; } Public BooleanIsOpen () {//direct return False, not opened return false; } PublicURL GetURL ()throwsIOException {//Leave subclass Rewrite Throw NewFileNotFoundException (GetDescription () + "cannot is resolved to URL"); } PublicURI GetURI ()throwsIOException {//return URLURL url =GetURL (); Try { returnResourceutils.touri (URL);//returns the URL after it is formatted } Catch(URISyntaxException ex) {Throw NewNestedioexception ("Invalid URI [" + URL + "]", ex); } } PublicFile GetFile ()throwsIOException {//Leave subclass Rewrite Throw NewFileNotFoundException (GetDescription () + "cannot is resolved to absolute file path"); } //This resource content length is actually the byte length of the resource, judged by reading it all over again. This method calls up a lot of resources Ah! Public LongContentLength ()throwsIOException {InputStream is= This. getInputStream (); Assert.state ( is!=NULL, "resource input stream must not is null");//Assertion Try { LongSize = 0; byte[] buf =New byte[255]; intRead; while(read = Is.read (BUF))! =-1) {size+=Read; } returnsize; } finally { Try{is.close (); } Catch(IOException ex) {}}} Public LongLastModified ()throwsIOException {//returns the last modified time for a resource LongLastModified =Getfileforlastmodifiedcheck (). LastModified (); if(LastModified = = 0L) { Throw NewFileNotFoundException (GetDescription () + "cannot is resolved in the file system for resolving it last -modified Timestamp "); } returnlastmodified; } //This is a method that the resource interface does not have, the comment means "return file, give timestamp check", ask subclass to rewrite ... protectedFile Getfileforlastmodifiedcheck ()throwsIOException {returnGetFile (); } PublicResource createrelative (String relativepath)throwsIOException {//Leave subclass Rewrite Throw NewFileNotFoundException ("Cannot create a relative resource for" +getdescription ()); } PublicString GetFileName () {//default returns Null (assuming the resource does not have a file name) unless the subclass overrides return NULL; } @Override PublicString toString () {//ToString Returns the file description returngetdescription (); } @Override Public BooleanEquals (Object obj) {//equals compares 2 resource descriptions. return(obj = = This||(objinstanceofResource &&((Resource) obj). GetDescription (). Equals (GetDescription ())); } @Override Public intHashcode () {//returns the hashcode of the resource description returngetdescription (). Hashcode (); }}
Conclusion:
1, added a method, protected file Getfileforlastmodifiedcheck () throws IOException, the subclass is required to implement, if the subclass is not implemented, then directly return the resource file. The concrete effect of this method, and then look at the implementation class.
2, Method ContentLength (), is a very heavy-weight method, which determines the number of bytes of a resource by reading the resource all over again. A 255-byte buffer array to read. Subclasses are generally rewritten. (Adjust the size of the buffer array?) )
3, GetDescription () is the only non-implementation of this abstract class interface method, left to the subclass to implement, the resource file default equals (), hashcode () through this to judge.
4, Inputstreamsource This ancestor interface of the only method getInputStream () is not implemented, left to the subclass.
Resource sub-interfaces Contextresource and Writableresource
These two interfaces inherit from resource and have all the methods of resource. Where the Contextresource interface adds a method:
// returns the path within the context
This method enables its implementation class to have the ability to return the current context path.
The Writableresource interface adds 2 methods:
boolean iswritable (); // whether writable throws//returns the write stream of the resource
This method enables its implementation class to have the ability to write resources.
PS: The frame feels most like this, not difficult, the design pattern also uses not much. But there is a kind of big Qiao not work, no front of the feeling, because the code is really very concise use.
Analysis of the source, to a large extent, also exercise their English document reading ability. Share.
Spring Source Analysis--Resource access tool resource interface and abstract class analysis