随笔:15 文章:8 评论:1 引用:0
BlogJava 首页 发新随笔
发新文章 联系 聚合管理




PureMVC结构

PureMVC框架的目标很明确,即把程序分为低耦合的三层:Model、View和Controller。
降低模块间的耦合性,各模块如何结合在一起工作对于创建易扩展,易维护的应用程序是非常重要的。

在PureMVC实现的经典MVC元设计模式中,这三部分由三个单例模式类管理,分别是Model、View和Controller。三者合称为核心层或核心角色。

PureMVC中还有另外一个单例模式类——Façade,Façade提供了与核心层通信的唯一接口,以简化开发复杂度。

    Model 与 Proxy

 


 

Model保存对Proxy对象的引用,Proxy负责操作数据模型,与远程服务通信存取数据。
这样保证了Model层的可移植性。

    View 与 Mediator

 


 

View保存对Mediator对象的引用。由Mediator对象来操作具体的视图组件(View Component,例如Flex的DataGrid组件),包括:添加事件监听器,发送或接收Notification ,直接改变视图组件的状态。

这样做实现了把视图和控制它的逻辑分离开来。

    Controller 与 Command

 


 

Controller保存所有Command的映射。Command类是无状态的,只在需要时才被创建。

Command可以获取Proxy对象并与之交互,发送Notification,执行其他的Command。经常用于复杂的或系统范围的操作,如应用程序的“启动”和“关闭”。应用程序的业务逻辑应该在这里实现。


    Façade 与 Core

 


 


Façade类应用单例模式,它负责初始化核心层(Model,View和Controller),并能访问它们的Public方法。

这样,在实际的应用中,你只需继承Façade类创建一个具体的Façade类就可以实现整个MVC模式,并不需要在代码中导入编写Model,View和Controller类。
Proxy、Mediator和Command就可以通过创建的Façade类来相互访问通信。

    Observer 与 Notification



PureMVC的通信并不采用Flash的EventDispatcher/Event,因为PureMVC可能运行在没有Flash Event和EventDispatcher类的环境中,它的通信是使用观察者模式以一种松耦合的方式来实现的。

你可以不用关心PureMVC的Observer/Notification机制是怎么实现的,它已经在框架内部实现了。你只需要使用一个非常简单的方法从Proxy, Mediator, Command和Facade发送Notification,甚至不需要创建一个Notification实例。

 



    Notification可以被用来触发Command的执行


Facade保存了Command与Notification之间的映射。当Notification(通知)被发出时,对应的Command(命令)就会自动地由Controller执行。Command实现复杂的交互,降低View和Model之间的耦合性。


Mediator发送、声明、接收Notification


当用View注册Mediator时,Mediator的listNotifications方法会被调用,以数组形式返回该Mediator对象所关心的所有Notification。
之后,当系统其它角色发出同名的Notification(通知)时,关心这个通知的Mediator都会调用handleNotification方法并将Notification以参数传递到方法。

Proxy发送,但不接收Notification


在很多场合下Proxy需要发送Notification(通知),比如:Proxy从远程服务接收到数据时,发送Notification告诉系统;或当Proxy的数据被更新时,发送Notification告诉系统。

如果让Proxy也侦听Notification(通知)会导致它和View(视图)层、Controller(控制)层的耦合度太高。

View和Controller必须监听Proxy发送的Notification,因为它们的职责是通过可视化的界面使用户能与Proxy持有的数据交互。
不过对View层和Controller层的改变不应该影响到Model层。

例如,一个后台管理程序和一个面向用户程序可能共用一个Model类。如果只是用例不同,那么View/Controller通过传递不同的参数就可以共用相同的Model类。


Façade


MVC元设计模式的核心元素在PureMVC中体现为Model类、View类和Controller类。为了简化程序开发,PureMVC应用了Façade模式。

Façade是Model、View和Controller三者的“经纪人”。实际编写代码时你并不用导入这三者的类文件,也不用直接使用它们。Façade类已经在构造方法包含了对核心MVC三者单例的构造。

一般地,实际的应用程序都有一个Façade子类,这个Façade类对象负责初始化Controller(控制器),建立Command与Notification名之间的映射,并执行一个Command注册所有的Model和View。

    具体Façade是什么样子的?

Façade类应被当成抽象类, 永远不被直接实例化。针对具体的应用程序,你应该具体编写Façade的子类,添加或重写Façade的方法来实现具体的应用。按照惯例,这个类命名为“ApplicationFacade”(当然,命名随你喜欢),如前所述,它主要负责访问和通知Command,Mediator和Proxy。

通常,不同的运行平台都会创建视图结构,尽管创建过程不一样。(比如Flex中MXML程序负责实例化所有子视图组件,Flash影片在Stage上构建可视对象)。视图结构构建完毕时,整个PureMVC机制也已经安置妥当。

创建的Facade子类也被用来简化“启动”的过程。应用程序调用Facade子类的startup方法,并传递自身的一个引用即完成启动,使得应用程序不需要过多了解PureMVC。


为程序创建Façade

Façade类的内容很简单。思考下面的例子:
 1package com.me.myapp
 2{
 3import org.puremvc.as3.interfaces.*;
 4import org.puremvc.as3..patterns.facade.*;
 5import com.me.myapp.view.*;
 6import com.me.myapp.model.*;
 7import com.me.myapp.controller.*;
 8// MyApp程序的Façade类
 9public class ApplicationFacade extends Façade implements IFacade
10{
11//定义Notification(通知)常量
12public static const STARTUP:String = "startup";
13public static const LOGIN:String = "login";
14//得到ApplicationFacade单例的工厂方法
15public static function getInstance() : ApplicationFacade
16{
17if ( instance == null ) instance = new ApplicationFacade( );
18return instance as ApplicationFacade;
19}

20//注册Command,建立Command与Notification之间的映射
21override protected function initializeController( ) : void
22{
23super.initializeController();
24registerCommand( STARTUP, StartupCommand );
25registerCommand( LOGIN, LoginCommand );
26registerCommand( LoginProxy.LOGIN_SUCCESS, GetPrefsCommand );
27}

28//启动PureMVC,在应用程序中调用此方法,并传递应用程序本身的引用 public function startup( app:MyApp ) : void
29{
30sendNotification( STARTUP, app );
31}

32}

33}


上述代码需要注意以下几点:
oApplicationFacade继承自PureMVC的Façade类,Façade类实现了IFacade接口。

o这个例子里ApplicationFacade没有重写构造方法。如果重写构造方法,应该在构造方法里先调用父类的构造方法。

o类方法getInstance用于返回ApplicationFacade的单例,并将实例保存在父类的一个protect变量中。在返回该实例之前必须先把它转化为ApplicationFacade类型。

o定义了Notification名称常量。Façade类是整个系统其他角色相互访问通信的核心,所以在这里定义Notification(通知)名称常量是最合适的。

o初始化Controller(控制器),并建立Command与Notification之间的映射,当Notification(通知)发出时相关的Command(命令)就会被执行。

o提供一个带有应用程序类型参数的startup方法,该参数能过Notification传递到StartupCommand。
posted @ 2009-02-22 14:30 TracyLu 阅读(648) | 评论 (0)编辑 收藏
 

There are times when the system throws a ClassCastException if you are casting an object of type A to type A (where A can be any class within your system). Doesn't make any sense, does it? Well, there is a good explanation to this problem that keeps confusing people working with Java environments especially with JSP:s and servlets.

Reason and technical background#

The understanding of this strange phenomenon goes down to the very basics of the Java virtual machine and its data structures. The cause of ClassCastException is technically a difference between two pointers (or references to be more exact) pointing to instances of java.lang.Class. For each object instance in Java we also need an instance of that java.lang.Class representing its bytecode and static allocations. Typically this instance of Class is shared among all objects of same type, which means that a.getClass() == b.getClass() if objects a and b are type MyClass.

The construction of Class objects is usually hidden from application developers and takes place when the JVM meets new object types (classes) for the first time. For example when the code says "new MyClass();" the system notices that there is no code for MyClass and the class loader gets activated. The loader loads the bytecode, allocates static fields and executes the static initializer. The next step after the class construction is to allocate an actual instance of the class. The JVM now calls the new java.lang.Class instance representing MyClass for a new instance, which allocates some memory for instance variables (non-static fields). One important part of this new allocation is a reference back to the actual class object that defines the object type. You can get this reference with getClass() method of the object to see its content.

In some special cases it is possible that there are two or more Class instances representing the same class (either with the same or different bytecode) with their own static areas. It is a common and incorrect belief that static fields are unique within the same virtual machine. Static areas are part of the class instance and since there can be several instances for the same class they all have their own copies of those fields (this is a fact that can be used to detect this problem). So, if we have an A and a B of types MyClass but their instances of MyClass code are different it means that a.getClass() != b.getClass() and we will get a ClassCastException if the code says:

 MyClass A = (MyClass)vector.elementAt(0); 
where the element is B. Confusing? Ok, let's take a closer look to the code. What is really happening is that "(MyClass)" expects that the parameter object has a reference to the class instance (or its class instance has recursively a base class reference to support inheritance) that would be exactly the same as the one given my the local class loader (this.getClass().getClassLoader()). This is important because although we might have the same class name we would still have wrong static allocations and perhaps even wrong bytecode if the instance would not be the same.

When does this happen?#

  • If there are several ClassLoaders and they do not share all their classes. Classes loaded with separate loaders cannot see Class objects from each other and reload binaries. This is usally the case when you are using applications servers and you have several applications that interact together.
  • If you are loading classes explicitly using Class.forName() or by passing their codes directly to the class loader. Explicit class construction can even be used to reconstruct the situation in question.
  • If you are using a system that automatically reloads classes that have been modified. This is usually the case with JSPs. The Servlet engine re-compiles JSPs and loads them although old instances still remain somewhere in memory. You might also meet this problem with some IDEs for the same reason.

Some possible ways to fix the problem#

You can try to specify the problematic classes in the beginning of the CLASSPATH of the default ClassLoader. This usually prevents custom loaders from creating their local copies because default classes are usually visible for all of them.

In case of the rare JSP problems it might be enough if you just restart the servlet engine after page modifications to dispose old classes.

Use explicit ClassLoader definitions in your code to makes sure that you are using the correct ClassLoader for all classes.

If you are getting this problem because you have written your own ClassLoader it usually means that you are not accessing the base loader properly. By default you should always ask if the default ClassLoader already has an instance for the requested class type.

If you are type casting an ActionForm to the appropriate bean, then you can simply use BeanUtils.getProperty(obj, property) to get the value.

Original author: Asser (Fixed some typos. -- ebu)
=================================================================================
Sun Glassfish Enterprise Server V2UR2 Class Loader Hieriachy:




So to avoid A 2 A ClassCastException, the class will be casted between deployed MBean and LifeCycle Module, we can put the class and dependency classes into Shared Chain ClassPath. I solved my problem this way.

posted @ 2009-02-19 08:48 TracyLu 阅读(228) | 评论 (0)编辑 收藏
 

  非可变对象一旦创建之后就不能再被改变,可变对象则可以在创建之后被改变。String对象是非可变对象,StringBuffer对象则是可变对象。为获得更佳的性能你需要根据实际情况小心谨慎地选择到底使用这两者中的某一个。下面的话题会作详细的阐述。(注意:这个章节假设读者已经具备Java的String和StringBuffer的相关基础知识。)
 
创建字符串的较佳途径
你可以按照以下方式创建字符串对象:
1. String s1 = "hello"; 
    String s2 = "hello"; 
2. String s3 = new String("hello");
    String s4 = new String("hello");
 
上面哪种方式会带来更好的性能呢?下面的代码片断用来测量二者之间的区别。

StringTest1.java
package com.performance.string;
/** This class shows the time taken for creation of
 *  String literals and String objects.
 */
public class StringTest1 {
public static void main(String[] args){
    // create String literals
    long startTime = System.currentTimeMillis();
    for(int i=0;i<50000;i++){
    String s1 = "hello";
    String s2 = "hello";
    }
    long endTime = System.currentTimeMillis();
    System.out.println("Time taken for creation of String literals : "
                  + (endTime - startTime) + " milli seconds" );
    // create String objects using 'new' keyword       
    long startTime1 = System.currentTimeMillis();
    for(int i=0;i<50000;i++){
    String s3 = new String("hello");
    String s4 = new String("hello");
    }
    long endTime1 = System.currentTimeMillis();
    System.out.println("Time taken for creation of String objects : "
                  + (endTime1 - startTime1)+" milli seconds");
    }
}
这段代码的输出:
Time taken for creation of String literals : 0 milli seconds
Time taken for creation of String objects : 170 milli seconds
 
JVM是怎样处理字符串的呢?
  Java虚拟机会维护一个内部的滞留字符串对象的列表(唯一字符串的池)来避免在堆内存中产生重复的String对象。当JVM从class文件里加载字符串字面量并执行的时候,它会先检查一下当前的字符串是否已经存在于滞留字符串列表,如果已经存在,那就不会再创建一个新的String对象而是将引用指向已经存在的String对象,JVM会在内部为字符串字面量作这种检查,但并不会为通过new关键字创建的String对象作这种检查。当然你可以明确地使用String.intern()方法强制JVM为通过 new关键字创建的String对象作这样的检查。这样可以强制JVM检查内部列表而使用已有的String对象。
  所以结论是,JVM会内在地为字符串字面量维护一些唯一的String对象,程序员不需要为字符串字面量而发愁,但是可能会被一些通过 new关键字创建的String对象而困扰,不过他们可以使用intern()方法来避免在堆内存上创建重复的String对象来改善Java的运行性能。下一小节会向大家展示更多的信息。
 
下图展示了未使用intern()方法来创建字符串的情况。
 
string_creating_without_intern() method
  你可以自己使用==操作符和String.equals()方法来编码测试上面提到的区别。==操作符会返回true如果一些引用指向一个相同的对象但不会判断String对象的内容是否相同;String.equals()方法会返回true如果被操作的String对象的内容相同。对于上面的代码会有s1==s2,因为s1和s2两个引用指向同一个对象,对于上面的代码,s3.equals(s4)会返回true因为两个对象的内容都一样为”hello”。你可以从上图看出这种机制。在这里有三个独立的包含了相同的内容(”hello”)的对象,实际上我们不需要这么三个独立的对象—— 因为要运行它们的话既浪费时间又浪费内存。
 
  那么怎样才能确保String对象不会重复呢?下一个话题会涵盖对于内建String机制的兴趣。
 
滞留字符串的优化作用
  同一个字符串对象被重复地创建是不必要的,String.intern ()方法可以避免这种情况。下图说明了String.intern()方法是如何工作的,String.intern()方法检查字符串对象的存在性,如果需要的字符串对象已经存在,那么它会将引用指向已经存在的字符串对象而不是重新创建一个。下图描绘了使用了intern()方法的字符串字面量和字符串对象的创建情况。
 
string_creating_with_intern() method
下面的例程帮助大家了解String.intern()方法的重要性。
StringTest2.java
 
package com.performance.string;
// This class shows the use of intern() method to improve performance
public class StringTest2 {
public static void main(String[] args){
    // create String references like s1,s2,s3...so on..
    String variables[] = new String[50000];
    for( int i=0;i<variables.length;i++){
        variables[i] = "s"+i;
    }
    // create String literals
    long startTime0 = System.currentTimeMillis();
    for(int i=0;i<variables.length;i++){
        variables[i] = "hello";
    }
    long endTime0 = System.currentTimeMillis();
    System.out.println("Time taken for creation of String literals : "
                         + (endTime0 - startTime0) + " milli seconds" );
    // create String objects using 'new' keyword       
    long startTime1 = System.currentTimeMillis();
    for(int i=0;i<variables.length;i++){
        variables[i] = new String("hello");
    }
    long endTime1 = System.currentTimeMillis();
    System.out.println("Time taken for creation of String objects with 'new' key word : "
                        + (endTime1 - startTime1)+" milli seconds");
    // intern String objects with intern() method   
    long startTime2 = System.currentTimeMillis();
    for(int i=0;i<variables.length;i++){
        variables[i] = new String("hello");
        variables[i] = variables[i].intern();
    }
    long endTime2 = System.currentTimeMillis();
    System.out.println("Time taken for creation of String objects with intern(): "
                        + (endTime2 - startTime2)+" milli seconds");
    }
}
这是上面那段代码的输出结果:
Time taken for creation of String literals : 0 milli seconds
Time taken for creation of String objects with 'new' key word : 160 milli seconds
Time taken for creation of String objects with intern(): 60 milli seconds
 
连接字符串时候的优化技巧
  你可以使用+操作符或者String.concat()或者StringBuffer.append()等办法来连接多个字符串,那一种办法具有最佳的性能呢?
  如何作出选择取决于两种情景,第一种情景是需要连接的字符串是在编译期决定的还是在运行期决定的,第二种情景是你使用的是 StringBuffer还是String。通常程序员会认为StringBuffer.append()方法会优于+操作符或 String.concat()方法,但是在一些特定的情况下这个假想是不成立的。
 
1) 第一种情景:编译期决定相对于运行期决定
请看下面的StringTest3.java代码和输出结果。

package com.performance.string;
/** This class shows the time taken by string concatenation at compile time and run time.*/
public class StringTest3 {
  public static void main(String[] args){
    //Test the String Concatination
    long startTime = System.currentTimeMillis();
    for(int i=0;i<5000;i++){
    String result = "This is"+ "testing the"+ "difference"+ "between"+
            "String"+ "and"+ "StringBuffer";
    }
    long endTime = System.currentTimeMillis();
    System.out.println("Time taken for string concatenation using + operator : "
         + (endTime - startTime)+ " milli seconds");
    //Test the StringBuffer Concatination
    long startTime1 = System.currentTimeMillis();
    for(int i=0;i<5000;i++){
    StringBuffer result = new StringBuffer();
         result.append("This is");
        result.append("testing the");
        result.append("difference");
        result.append("between");
       result.append("String");
       result.append("and");
       result.append("StringBuffer");
     }
    long endTime1 = System.currentTimeMillis();
    System.out.println("Time taken for String concatenation using StringBuffer : "
           + (endTime1 - startTime1)+ " milli seconds");
  }
}
这是上面的代码的输出结果:
Time taken for String concatenation using + operator : 0 milli seconds
Time taken for String concatenation using StringBuffer : 50 milli seconds
很有趣地,+操作符居然比StringBuffer.append()方法要快,为什么呢?
 
  这里编译器的优化起了关键作用,编译器像下面举例的那样简单地在编译期连接多个字符串。它使用编译期决定取代运行期决定,在你使用new关键字来创建String对象的时候也是如此。
 
编译前:
String result = "This is"+"testing the"+"difference"+"between"+"String"+"and"+"StringBuffer";
编译后:
String result = "This is testing the difference between String and StringBuffer";

这里String对象在编译期就决定了而StringBuffer对象是在运行期决定的。运行期决定需要额外的开销当字符串的值无法预先知道的时候,编译期决定作用于字符串的值可以预先知道的时候,下面是一个例子。
 
编译前:
public String getString(String str1,String str2) {
    return str1+str2;
}
编译后:
return new StringBuffer().append(str1).append(str2).toString();
运行期决定需要更多的时间来运行。
 
2) 第二种情景:使用StringBuffer取代String
看看下面的代码你会发现与情景一相反的结果——连接多个字符串的时候StringBuffer要比String快。
StringTest4.java
 
package com.performance.string;
/** This class shows the time taken by string concatenation
using + operator and StringBuffer  */
public class StringTest4 {
 public static void main(String[] args){
    //Test the String Concatenation using + operator
    long startTime = System.currentTimeMillis();
    String result = "hello";
    for(int i=0;i<1500;i++){
        result += "hello";
    }
    long endTime = System.currentTimeMillis();
    System.out.println("Time taken for string concatenation using + operator : "
                  + (endTime - startTime)+ " milli seconds");
    //Test the String Concatenation using StringBuffer
    long startTime1 = System.currentTimeMillis();
    StringBuffer result1 = new StringBuffer("hello");
    for(int i=0;i<1500;i++){
        result1.append("hello");
    }
    long endTime1 = System.currentTimeMillis();
    System.out.println("Time taken for string concatenation using StringBuffer :  "
                  + (endTime1 - startTime1)+ " milli seconds");
    }
}
这是上面的代码的输出结果:
Time taken for string concatenation using + operator : 280 milli seconds
Time taken for String concatenation using StringBuffer : 0 milli seconds
看得出StringBuffer.append()方法要比+操作符要快得多,为什么呢?

  原因是两者都是在运行期决定字符串对象,但是+操作符使用不同于StringBuffer.append()的规则通过String和StringBuffer来完成字符串连接操作。(译注:什么样的规则呢?)
 
借助StringBuffer的初始化过程的优化技巧
  你可以通过StringBuffer的构造函数来设定它的初始化容量,这样可以明显地提升性能。这里提到的构造函数是StringBuffer(int length),length参数表示当前的StringBuffer能保持的字符数量。你也可以使用ensureCapacity(int minimumcapacity)方法在StringBuffer对象创建之后设置它的容量。首先我们看看StringBuffer的缺省行为,然后再找出一条更好的提升性能的途径。
 
StringBuffer的缺省行为:
  StringBuffer在内部维护一个字符数组,当你使用缺省的构造函数来创建StringBuffer对象的时候,因为没有设置初始化字符长度,StringBuffer的容量被初始化为16个字符,也就是说缺省容量就是16个字符。当StringBuffer达到最大容量的时候,它会将自身容量增加到当前的2倍再加2,也就是(2*旧值+2)。
  如果你使用缺省值,初始化之后接着往里面追加字符,在你追加到第16个字符的时候它会将容量增加到34(2*16+2),当追加到34个字符的时候就会将容量增加到70(2*34+2)。无论何事只要StringBuffer到达它的最大容量它就不得不创建一个新的字符数组然后重新将旧字符和新字符都拷贝一遍——这也太昂贵了点。所以总是给StringBuffer设置一个合理的初始化容量值是错不了的,这样会带来立竿见影的性能增益。
  我利用两个StringBuffer重新测试了上面的StringTest4.java代码,一个未使用初始化容量值而另一个使用了。这次我追加了50000个’hello’对象没有使用+操作符。区别是我使用StringBuffer(250000)的构造函数来初始化第二个 StringBuffer了。
 
输出结果如下:
Time taken for String concatenation using StringBuffer with out setting size: 280 milli seconds
Time taken for String concatenation using StringBuffer with setting size: 0 milli seconds
StringBuffer初始化过程的调整的作用由此可见一斑。所以,使用一个合适的容量值来初始化StringBuffer永远都是一个最佳的建议。
 
关键点
1. 无论何时只要可能的话使用字符串字面量来常见字符串而不是使用new关键字来创建字符串。
2. 无论何时当你要使用new关键字来创建很多内容重复的字符串的话,请使用String.intern()方法。
3. +操作符会为字符串连接提供最佳的性能——当字符串是在编译期决定的时候。
4. 如果字符串在运行期决定,使用一个合适的初期容量值初始化的StringBuffer会为字符串连接提供最佳的性能。

posted @ 2009-02-14 16:22 TracyLu 阅读(141) | 评论 (0)编辑 收藏
 
        Java管理扩展(也叫做JMX规范)在Java编程语言中定义了应用程序以及网络管理和监控的体系结构、设计模式、应用程序接口以及服务。本章介绍所有这些元素,宽泛地呈现这些扩展。JMX规范为跨所有企业的Java开发者编写java工具、创建智能代理、实现分布式管理中间件、管理程序以及向现存管理和监控系统平滑集成上述方案提供了方法。此外,JMX规范针对现存的标准管理和监控技术参考了大量的Java APIs。
  
      需要注意,全文余下的部分所提到的文档和管理的概念均因用自管理和监控服务。

      JMX 架构被分成3个层次:

     设备层(Instrumentation Level)
     代理层(Agent Level)
     分布式服务层(Distributed Service Level)    

     本章对各层加以介绍并描述他们基本的组件。

      1.1 JMX架构的优点
    
      通过执行JMX规范,将从JMX规范中获得下列益处:

      (1)使得Java应用程序在无巨大投资的情况下能够被管控
      JMX架构依赖于一个核心受控对象服务器,该服务器作为一个管理代理运行在大多数Java使能的设备上。这使得Java应用程序能够对其设计影响很小的情况下被管控。一个Java应用程序只需简单的嵌入一个受控对象服务器并且将其一些功能设计成为为一个或多个注册在对象服务器中的受控Beans(MBeans)即可。这些就是从管理基础结构中受益所需花费的全部成本。
    JMX提供了一个标准的方法以使任何基于Java的应用程序、服务或者设备受管。比如,企业级JavaBean应用程序能够遵从JMX架构以使其可以被管理。

     (2)提供了可升级扩展的管理体系结构
     每一个JMX代理服务都是一个独立的模块,满足必要条件后,可以插入到管理代理中。这种基于组件的方法意味着JMX解决方案可以从节省空间的设备升级扩展到电信领域的交换机,并可以向更大级别继续升级扩展。
     JMX规范提供了一系列核心的代理服务。额外的服务将会Comformant Implementations和众多管理方案集大成者来开发。所有这些服务都可以在管理基础架构中被动态的加载,卸载和更新。

     (3)集成现有的管理方案
     JMX智能代理可以通过HTML浏览器或者大量管理协议,如SNMP和WBEM,实现受控。JMX API是开放的接口,任何管理系统供应商都可以使用。
  
    (4)增强现有标准的Java技术
     任何时候只要需要,JMX规范将会参考现有的Java规范,如JNDI,JDBC,JTS等等。

    (5)丰富未来的管理概念
    JMX规范的API可以灵活动态的实现管理方案,通过Java编程语言,来增强显现的技术。例如,JMX方案能够使用查找和发现服务和一些协议,如Jini网络技术,UPNP和服务定位协议。
    在Sun公司给出的演示中,Jini网络技术提供了对网络中的资源和服务的自发发现技术,然后这些资源和服务通过一个JMX应用程序被管理起来。将这两种能力组合起来被称为Sun 自发管理软件。

    (6)仅定义了管理必备的接口
    JMX API并没有设计成通用目的的分布式对象系统。虽然它提供了很多被设计成为适用于分布式环境的服务,这些的目标依然是提供网络,系统以及应用程序的管理功能。

1.2 规范的范围
JMX规范定义了一个管理体系结构以及一套描述了该架构中组件的API。这些API涵盖了管理者和代理两方面的功能,向管理应用程序开发人员提供了应允的的实现。

这篇JMX规范文档陈述了管理体系架构中的整个三个层次。他们是:

(1)设备规范
(2)代理规范
(3)分布式服务规范

1.2.1引用实现
引用实现是第一个可工作的实现了JMX规范的应用程序,委托给JCP定义Java编程语言的扩展。引用实现是由Sun公司开发,作为JMX规范的领军团体,针对设备以及代理两方面规范进行的实现。

对于JMX 1.3版本的API, 引用实现对于规范来说是不可分割的一部分。那个引用实现现在已成为编号为“Mustang”的Java平台标准第六版的一部分。

1.2.2兼容测试套件
JMX规范的兼容测试套件(CTS)用来检查是否和JMX实现标准吻合。这一套件也同样委托给JCP。这个套件检验了声称遵从某一具体JMX规范部分的应用程序的每一个规范点。该套件也是Sun公司开发,并由其主导。

由于JMX规范定义的类对Java平台来说是可选的包,CTS作为一个兼容性工具包由JavaTest软件来运行。

JMX规范的每一个部分都能够确定为必选和可选组件。一个JMX兼容的实现必须提供所有必选服务,并且提供可悬服务的任何子集,但是这些必须遵从规范。

当声明了JMX兼容性,实现将列出所支持的可选服务,并且经过CTS对于规范性陈述的测试。这要求了CTS中的一些模块能够针对很多那种仅近是规范自集的实现来进行测试。


1.2.3 JMX API 作为Java平台的一部分

对于5.0的Java 2平台,编号为“Tiger”的标准版,JMX API和 JMX Remote API是该平台核心的一部分。Tiger包含了JMX版本1.2的API和版本1.0的JMX Remote API。本规范所覆盖的API被Java平台6所囊括。任何一个代替品必须通过CTS的每一项测试。

该规范对于MXBeans部分,定义了注释将产生的一些行为,如出现了@java.beans.ConstructorProperties。而该注视并未出现在Tiger平台当中,产生的行为问题不会出现在该平台中。

1.3 架构总观

 
posted @ 2009-02-13 17:02 TracyLu 阅读(660) | 评论 (0)编辑 收藏
 
posted @ 2009-02-13 16:03 TracyLu 阅读(114) | 评论 (0)编辑 收藏
 
Just browsing,thanks. 谢谢,我只是逛逛。
No,thanks.Just browsing.Maybe later Imight need your help.不,谢谢。我只是逛逛。可能过一会需要你的帮忙。
No,Just browsing.I have nothing to buy.不,我只是逛逛,不想买什么。
posted @ 2009-02-13 15:46 TracyLu 阅读(104) | 评论 (0)编辑 收藏
 
public class MakeDir{
   
public static void main(){
     String fileString 
= "c:\\test\\do\\test.txt";
     File file 
= new File("fileString");
     MakeDir makeDir = new MakeDir();
         makeDir.make(file);
   }

   
public void make(File file){
     
if(file.exists()){
        
if(file.isFile()){
           file.delete();
        }
else{
           
return;
        }

     }
else{
        
if(file.getParentFile().exists()){
           
return;
        }
else{
           make(file.getParentFile());
           file.getParentFile.mkdir();
           
return;
        }
  
     }

   }

}
posted @ 2009-02-13 14:53 TracyLu 阅读(151) | 评论 (0)编辑 收藏
 

1、java.lang包:java的核心类库,包含了运行java程序必不可少的系统类,如基本数据类型、基本数学函数、字符串处理、线程、异常处理类等,系统缺省加载这个包
2、java.io包:java语言的标准输入/输出类库,如基本输入/输出流、文件输入/输出、过滤输入/输出流等等
3、java.util包:包含如处理时间的date类,处理变成数组的Vector类,以及stack和HashTable类
4、java.awt包:构建图形用户界面(GUI)的类库,低级绘图操作Graphics类,图形界面组件和布局管理如Checkbox类、Container类、LayoutManger接口等,以及界面用户交互控制和事件响应,如Event类
5、java.awt.image包:处理和操纵来自于网上的图片的java工具类库
6、java.applet包
7、java.net包:实现网络功能的类库有Socket类、ServerSocket类
8、java.lang.reflect包:提供用于反射对象的工具
9、java.util.zip包:实现文件压缩功能
10、java.awt.datatransfer包:处理数据传输的工具类,包括剪贴板,字符串发送器等
11、java.awt.event包
12、java.sql包:实现JDBC的类库

posted @ 2009-02-12 14:41 TracyLu 阅读(146) | 评论 (0)编辑 收藏
 
类介绍     http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/lang/ClassLoader.html#name 

相关文章:http://blog.csdn.net/luanxj/archive/2008/02/15/2096657.aspx
                    http://tech.ccidnet.com/art/5929/20071106/1266135_1.html
                    http://www.jdon.com/article/15456.html
posted @ 2009-02-12 14:21 TracyLu 阅读(101) | 评论 (0)编辑 收藏
 
越来越发现,设计是一种艺术,需要很细致的推敲,拿构造函数举例,设计一个类的构造函数也很讲究,是否应该公开默认的构造函数,该类是否有在创建时就必须非空的属性,这些非空的属性中,哪些是必须有意义的数据,哪些必须赋值,哪些默认即可,哪些属性不能更改,哪些属性是系统生成的并且对用户透明,都会影响构造器的设计。
posted @ 2009-02-11 18:01 TracyLu 阅读(129) | 评论 (0)编辑 收藏
仅列出标题
共3页: 上一页 1 2 3 下一页 
CALENDER
<2024年12月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

常用链接

留言簿(2)

随笔分类

随笔档案

文章分类

网站链接

搜索

  •  

最新评论

阅读排行榜

评论排行榜


Powered By: 博客园
模板提供沪江博客