In many cases, some custom classloader is used instead of the system class loader. Most of the time, people do this because they cannot predict which classes are needed during the runtime during compilation. Especially in those appservers, such as Tomcat, aveon-phonix, and JBoss. OrProgramSome plug-in functions are provided. You can add your own functions after the program is compiled, such as Ant and JXTA-shell. It is easy to customize a classloader. Generally, you only need to understand a few methods.
A simple custom classloader inherits from the classloader class. Here we need to create a classloader that can specify a path at runtime to load the class under this path.
Generally, we use the classloader. loadclass (string): class method. By providing a class name, we will get a corresponding class instance. Therefore, as long as we make a small change to this method, we can achieve our aspirations.
Source code:
- Protected Synchronized ClassLoadclass (StringName,BooleanRESOLVE)Throws Classnotfoundexception{
-
- // First, check if the class has already been loaded
-
- ClassC = findloadedclass (name );
-
- If(C =Null){
-
- Try{
-
- If(Parent! =Null){
- C = parent. loadclass (name,False);
-
- }Else{
-
- C = findbootstrapclass0 (name );
-
- }
-
- }Catch(ClassnotfoundexceptionE ){
-
- // If still not found, then call findclass in order
- // To find the class.
-
- C = findclass (name );
-
- }
-
- }
-
- If(RESOLVE ){
-
- Resolveclass (C );
-
- }
-
- ReturnC;
-
- }
Source from classloader. Java First, check javaapi DOC: the steps of the default loadclass method are shown above.
1. call findloadedclass (string): The class checks whether the class has been loaded. The JVM specification specifies that classloader can cache the class it loads, therefore, if a class has been loaded, you can directly obtain it from the cache.
2. Call its parent loadclass () method. If the parent is empty, use the Class Loader (the famous Bootstrap classloader) in the JVM ).
3. If neither of the above two steps is found, call the findclass (string) method to find and load the class.
There is another saying that after Java 1.2, we encourage users to inherit the findclass (string) method to implement their own class loader instead of inheriting the loadclass (string) method.
In this case, we will do this first :)
-
- Public ClassAnotherclassloaderExtends Classloader{
-
- Private StringBasedir;Private Static FinalLogger log =
- Logger. getlogger (anotherclassloader.Class);
-
- PublicAnotherclassloader (ClassloaderParent,StringBasedir ){
-
- Super(Parent );
-
- This. Basedir = basedir;
-
- }
-
- Protected ClassFindclass (StringName)
-
- Throws Classnotfoundexception{
- Log. debug ("findclass" + name );
-
- Byte[] Bytes = loadclassbytes (name );
-
- ClassTheclass = defineclass (name, bytes, 0, bytes.Length);//
-
- If(Theclass =Null)
-
- Throw New Classformaterror();
-
- ReturnTheclass;
-
- }
- Private Byte[] Loadclassbytes (StringClassname)Throws
-
- Classnotfoundexception{
-
- Try{
-
- StringClassfile = getclassfile (classname );
-
- Fileinputstream FCM =NewFileinputstream (classfile );
-
- Filechannel filec = FS. getchannel ();
- Bytearrayoutputstream baos =NewBytearrayoutputstream ();
-
- Writablebytechannel outc = channels. newchannel (baos );
-
- Bytebuffer buffer = bytebuffer. allocatedirect (1024 );
-
- While(True){
-
- IntI = filec. Read (buffer );
-
- If(I = 0 | I =-1 ){
- Break;
-
- }
-
- Buffer. Flip ();
-
- Outc. Write (buffer );
-
- Buffer. Clear ();
-
- }
-
- FCM. Close ();
- ReturnBaos. tobytearray ();
-
- }Catch(Ioexception fnfe ){
-
- Throw New Classnotfoundexception(Classname );
-
- }
-
- }
-
- Private StringGetclassfile (StringName ){
-
- StringbufferSB =New Stringbuffer(Basedir );
- Name = Name. Replace ('.', file. separatorchar) + ". Class ";
-
- SB. append (file. Separator + name );
-
- ReturnSB. tostring ();
-
- }
-
- }
[I] PS: here we use NiO of jdk1.4Code:) [/I]
Very simple code. The key is in A. We use the defineclass method to convert the binary array obtained from the class file to the corresponding class instance. Defineclass is a native method. It identifies the class file format for us, analyzes and reads the corresponding data structure, and generates a class instance. Before we finish, we just found the class released in a directory, and there are resources. Sometimes we use class. getresource (): URL to obtain the corresponding resource file. If the above classloader is used only, the corresponding return value is null. Let's take a look at the internal structure of the original classloader.
- PublicJava.net.URLGetresource (StringName ){
- Name = resolvename (name );
- ClassloaderCL = getclassloader0 ();// Here
- If(CL =Null){
- // A system class.
- Return Classloader. Getsystemresource (name );
- }
- ReturnCl. getresource (name );}
It turns out that the classloader that loads this class gets the resource.
- PublicURL getresource (StringName ){
- URL;
- If(Parent! =Null){
- Url = parent. getresource (name );
- }Else{
- Url = getbootstrapresource (name );
- }
- If(Url =Null){
- Url = findresource (name );// Here
- }
- ReturnURL;
- }
In this case, you only need to inherit the findresource (string) method. Modify the following code:
-
- // A new findresource Method
- ProtectedURL findresource (StringName ){
-
- Log. debug ("findresource" + name );
-
- Try{
-
- URL url =Super. Findresource (name );
-
- If(URL! =Null)
-
- ReturnURL;
-
- Url =NewURL ("file: //" + convername (name ));
- // Simplified processing. All resources are obtained from the file system.
-
- ReturnURL;
-
- }Catch(Malformedurlexception mue ){
-
- Log. Error ("findresource", mue );
-
- Return Null;
-
- }
-
- }
-
- Private StringConvername (StringName ){
- StringbufferSB =New Stringbuffer(Basedir );
-
- Name = Name. Replace ('.', file. separatorchar );
-
- SB. append (file. Separator + name );
-
- ReturnSB. tostring ();
-
- }
Now, a simple custom classloader is ready. You can add other spices (such as security check and class file modification) to suit your taste :) ----------------
I am not guru, but nonsenser
copyright notice: Write to the author | & Lt; TD align = "right" width = "70%" & gt;
This article does the article help you? Vote: Yes NO voting result: 9 0 |
|
other articles by the author:
- P2P introduction
- Tomcat reload, story to be told
- JMX notes ---- Part I (hellojmx)
- Top Ten Reasons for Java III!
- JAVA idioms-parameter classes (from C2)
all articles by the author |
|