<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>


    posts - 10,comments - 4,trackbacks - 0
    java虛擬機(jī)可能是下面三個(gè)中的一個(gè)
    1:抽象規(guī)范
    2:一個(gè)具體實(shí)現(xiàn)
    3:一個(gè)虛擬機(jī)實(shí)例

    java虛擬機(jī)的生命周期
    java虛擬機(jī)的天職就是:運(yùn)行一個(gè)java程序.當(dāng)一個(gè)java程序運(yùn)行開(kāi)始運(yùn)行時(shí),一個(gè)虛擬機(jī)實(shí)例就產(chǎn)生了.當(dāng)一個(gè)計(jì)算機(jī)上同時(shí)運(yùn)行三個(gè)java程序.則將產(chǎn)生三個(gè)java虛擬機(jī)實(shí)例.每個(gè)程序運(yùn)行在自己的虛擬機(jī)里面,不會(huì)干擾.當(dāng)程序運(yùn)行完畢時(shí),虛擬機(jī)將自動(dòng)退出.

    java虛擬機(jī)里面有兩種線程,守護(hù)線程和非守護(hù)線程.守護(hù)線程是說(shuō)java虛擬機(jī)自己的線程,如垃圾收集線程.而非守護(hù)線程則是java中運(yùn)行的程序線程.當(dāng)非守護(hù)線程都運(yùn)行完了.java虛擬機(jī)將退出.

    一個(gè)java虛擬機(jī)主要包括了:類轉(zhuǎn)載子系統(tǒng),運(yùn)行時(shí)數(shù)據(jù)區(qū),執(zhí)行引擎,內(nèi)存區(qū)等等.

    運(yùn)行時(shí)數(shù)據(jù)區(qū)------主要是:1 堆 2? 方法區(qū) 3 java棧

    堆和方法區(qū)對(duì)虛擬機(jī)實(shí)例中所有的對(duì)象都是共享的.而java棧區(qū),是對(duì)每個(gè)線程都是獨(dú)立的. 當(dāng)一個(gè)class被載入到 classloader中時(shí),會(huì)解析它的類型信息.把這些類型信息放到方法區(qū),而把程序中運(yùn)行的對(duì)象,放到堆區(qū).當(dāng)一個(gè)新線程被創(chuàng)建,就分配一個(gè)新的java棧.java棧中保存的,是方法中的一些變量,狀態(tài).java棧是由很多的java棧幀組成的.一個(gè)棧幀包含了一個(gè)方法運(yùn)行的狀態(tài).當(dāng)一個(gè)方法被執(zhí)行的時(shí)候,就壓入一個(gè)新的java棧幀到j(luò)ava棧中,方法返回的時(shí)候,就把棧幀彈出來(lái),拋棄掉.


    方法區(qū)

    在java虛擬機(jī)中,被裝載的類的類型信息和類的靜態(tài)變量被存儲(chǔ)在方法區(qū)這樣的內(nèi)存里面.java程序運(yùn)行時(shí),會(huì)查找這些個(gè)信息.方法區(qū)的大小,是動(dòng)態(tài)的.也可以不是連續(xù)的.可自由在堆中分配.也可以由用戶或者程序員指定.方法區(qū)可被垃圾收集.

    方法區(qū)可以保存以下信息
    這個(gè)類型的全限定名
    直接超類的全限定名
    是類類型還是接口
    類型的訪問(wèn)修飾符
    任何直接超類接口的全限定名的有序列表.
    該類型的常量池
    字段信息 類中聲明的每個(gè)字段及其順序 如字段名,類型.修飾符號(hào).
    方法信息:如方法名,返回類型.參數(shù)表列.修飾符號(hào).字節(jié)碼.操作數(shù)棧和棧幀中局部變量區(qū)大小等等
    類靜態(tài)變量
    一個(gè)到類classloader的引用
    一個(gè)到class類的引用



    用來(lái)存儲(chǔ)運(yùn)行時(shí)的對(duì)象實(shí)例

    java棧
    每啟動(dòng)一個(gè)新的線程.就會(huì)分配到一個(gè)java棧.java棧以幀為單位保存線程的運(yùn)行狀態(tài).它有兩種操作.入棧,出棧.
    當(dāng)一個(gè)方法被調(diào)用時(shí),入棧,當(dāng)一個(gè)方法返回時(shí),出棧,或者當(dāng)方法出現(xiàn)異常.也出棧.

    棧幀
    組成部分 局部變量區(qū),操作數(shù)棧,幀數(shù)據(jù)區(qū).
    posted @ 2006-04-05 18:25 dodoma 閱讀(378) | 評(píng)論 (1)編輯 收藏
    Eliminate obsolete object references消除過(guò)期的對(duì)象引用
    When you switch from a language with manual memory management, such as C or C++, to agarbage-collected language, your job as a programmer is made much easier by the fact that your objects are automatically reclaimed when you're through with them. It seems almost like magic when you first experience it. It can easily lead to the impression that you don't have to think about memory management, but this isn't quite true.
    java中也要注意內(nèi)存管理

    // Can you spot the "memory leak"?
    public class Stack {
    private Object[] elements;
    private int size = 0;
    public Stack(int initialCapacity) {
    this.elements = new Object[initialCapacity];
    }
    Effective Java: Programming Language Guide
    17
    public void push(Object e) {
    ensureCapacity();
    elements[size++] = e;
    }
    public Object pop() {
    if (size == 0)
    throw new EmptyStackException();
    return elements[--size];
    }
    /**
    * Ensure space for at least one more element, roughly
    * doubling the capacity each time the array needs to grow.
    */
    private void ensureCapacity() {
    if (elements.length == size) {
    Object[] oldElements = elements;
    elements = new Object[2 * elements.length + 1];
    System.arraycopy(oldElements, 0, elements, 0, size);
    }
    }
    }

    這里有一個(gè)內(nèi)存泄漏
    如果一個(gè)棧先是增長(zhǎng),然后再收縮,那么,從棧中彈出來(lái)的對(duì)象將不會(huì)被當(dāng)做垃圾回收,即使使用棧的客戶程序不再引用這些對(duì)象,它們也不會(huì)被回收。這是因?yàn)?,棧?nèi)部維護(hù)著對(duì)這些對(duì)象的過(guò)期引用(obsolete re f e re n c e)。所謂過(guò)期引用,是指永遠(yuǎn)也不會(huì)再被解除的引用

    改正
    public Object pop() {
    if (size==0)
    throw new EmptyStackException();
    Object result = elements[--size];
    elements[size] = null; // Eliminate obsolete reference清除引用
    return result;
    }

    當(dāng)程序員第一次被類似這樣的問(wèn)題困擾的時(shí)候,他們往往會(huì)過(guò)分小心:對(duì)于每一個(gè)對(duì)象引用,一旦程序不再用到它,就把它清空。這樣做既沒(méi)必要,也不是我們所期望的,因?yàn)檫@樣做會(huì)把程序代碼弄得很亂,并且可以想像還會(huì)降低程序的性能。“清空對(duì)象引用”這樣的操作應(yīng)該是一種例外,而不是一種規(guī)范行為。消除過(guò)期引用最好的方法是重用一個(gè)本來(lái)已經(jīng)包含對(duì)象引用的變量,或者讓這個(gè)變量結(jié)束其生命周期。如果你是在最緊湊的作用域范圍內(nèi)定義每一個(gè)變量(見(jiàn)第2 9條),則這種情形就會(huì)自然而然地發(fā)生。應(yīng)該注意到,在目前的J V M實(shí)現(xiàn)平臺(tái)上,僅僅退出定義變量的代碼塊是不夠的,要想使引用消失,必須退出包含該變量的方法。

    一般而言,只要一個(gè)類自己管理它的內(nèi)存,程序員就應(yīng)該警惕內(nèi)存泄漏問(wèn)題。一旦一個(gè)元素被釋放掉,則該元素中包含的任何對(duì)象引用應(yīng)該要被清空。

    內(nèi)存泄漏的另一個(gè)常見(jiàn)來(lái)源是緩存。一旦你把一個(gè)對(duì)象引用放到一個(gè)緩存中,它就很容易被遺忘掉,從而使得它不再有用之后很長(zhǎng)一段時(shí)間內(nèi)仍然留在緩存中
    posted @ 2006-03-31 16:35 dodoma 閱讀(205) | 評(píng)論 (0)編輯 收藏
    Avoid creating duplicate objects避免創(chuàng)建重復(fù)的對(duì)象
    It is often appropriate to reuse a single object instead of creating a new functionally equivalent object each time it is needed. Reuse can be both faster and more stylish. An object can always be reused if it is immutable

    String s = new String("silly"); // DON'T DO THIS!

    String s = "No longer silly";//do this

    In addition to reusing immutable objects, you can also reuse mutable objects that you know will not be modified. Here is a slightly more subtle and much more common example of what not to do, involving mutable objects that are never modified once their values have been computed:
    除了重用非可變的對(duì)象之外,對(duì)于那些已知不會(huì)被修改的可變對(duì)象,你也可以重用它們。

    such as
    public class Person {
    private final Date birthDate;
    // Other fields omitted
    public Person(Date birthDate) {
    this.birthDate = birthDate;
    }
    // DON'T DO THIS!
    public boolean isBabyBoomer() {
    Calendar gmtCal =
    Calendar.getInstance(TimeZone.getTimeZone("GMT"));
    gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
    Date boomStart = gmtCal.getTime();
    gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
    Date boomEnd = gmtCal.getTime();
    return birthDate.compareTo(boomStart) >= 0 &&
    birthDate.compareTo(boomEnd) < 0;
    }
    }

    改良的版本.
    The isBabyBoomer method unnecessarily creates a new Calendar, TimeZone, and two Date instances each time it is invoked. The version that follows avoids this inefficiency with a static initializer:

    class Person {
    private final Date birthDate;
    public Person(Date birthDate) {
    this.birthDate = birthDate;
    }
    /**
    * The starting and ending dates of the baby boom.
    */
    private static final Date BOOM_START;
    private static final Date BOOM_END;
    static {
    Calendar gmtCal =
    Calendar.getInstance(TimeZone.getTimeZone("GMT"));
    gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
    BOOM_START = gmtCal.getTime();
    gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
    BOOM_END = gmtCal.getTime();
    }
    public boolean isBabyBoomer() {
    return birthDate.compareTo(BOOM_START) >= 0 &&
    birthDate.compareTo(BOOM_END) < 0;
    }
    }

    。一個(gè)適配器是指這樣一個(gè)對(duì)象:它把功能委
    托給后面的一個(gè)對(duì)象,從而為后面的對(duì)象提供一個(gè)可選的接口。由于適配器除了后面的對(duì)象之外,沒(méi)有其他的狀態(tài)信息,所以針對(duì)某個(gè)給定對(duì)象的特定適配器而言,它不需要?jiǎng)?chuàng)建多個(gè)適配器實(shí)例。

    This item should not be misconstrued to imply that object creation is expensive and should be avoided. On the contrary, the creation and reclamation of small objects whose constructors do little explicit work is cheap, especially on modern JVM implementations. Creating additional objects to enhance the clarity, simplicity, or power of a program is generally a good thing.
    Conversely, avoiding object creation by maintaining your own object pool is a bad idea unless the objects in the pool are extremely heavyweight. A prototypical example of an object that does justify an object pool is a database connection. The cost of establishing the connection is sufficiently high that it makes sense to reuse these objects. Generally speaking, however, maintaining your own object pools clutters up your code, increases memory footprint, and harms performance. Modern JVM implementations have highly optimized garbage collectors that easily outperform such object pools on lightweight objects.
    posted @ 2006-03-31 15:19 dodoma 閱讀(204) | 評(píng)論 (0)編輯 收藏
    Enforce noninstantiability with a private constructor用一個(gè)私有的構(gòu)造函數(shù)來(lái)讓一個(gè)類不可以實(shí)例化

    Occasionally you'll want to write a class that is just a grouping of static methods and static fields.有時(shí)候,你想寫一個(gè)類,只是需要他提供了一系列的函數(shù)操作等,而不想讓它實(shí)例化.如:java.lang.Math or java.util.Arrays.
    但是如果你不提供構(gòu)造函數(shù),編譯器會(huì)自動(dòng)添加一個(gè).
    所以必須提供一個(gè).此時(shí),把構(gòu)造函數(shù)設(shè)置為private.就可以達(dá)到目的.
    一般用與工具類.

    // Noninstantiable utility class
    public class UtilityClass {
    // Suppress default constructor for noninstantiability
    private UtilityClass() {
    // This constructor will never be invoked
    }
    ... // Remainder omitted
    }

    由于private的構(gòu)咱函數(shù),該類不能被實(shí)例化.同時(shí).不能被繼承了.
    posted @ 2006-03-30 22:22 dodoma 閱讀(216) | 評(píng)論 (0)編輯 收藏
    Enforce the singleton property with a private constructor(用私有構(gòu)造函數(shù)執(zhí)行單例singlton)

    A singleton is simply a class that is instantiated exactly once [Gamma98, p. 127].如數(shù)據(jù)庫(kù)資源等.
    There are two approaches to implementing singletons. Both are based on keeping the
    constructor private and providing a public static member to allow clients access to the sole
    instance of the class. In one approach, the public static member is a final field:
    // Singleton with final field
    public class Elvis {
    public static final Elvis INSTANCE = new Elvis();
    private Elvis() {
    ...
    }
    ... // Remainder omitted
    }

    1:構(gòu)造函數(shù)私有
    2:提供一個(gè)靜態(tài)static的final成員

    The private constructor is called only once, to initialize the public static final field
    Elvis.INSTANCE.?
    Exactly one Elvis instance will exist once the Elvis class is initialized—no more,
    no less. Nothing that a client does can change this.

    In a second approach, a public static factory method is provided instead of the public static final field:
    // Singleton with static factory
    public class Elvis {
    private static final Elvis INSTANCE = new Elvis();
    private Elvis() {
    ...
    }
    public static Elvis getInstance() {
    return INSTANCE;
    }
    ... // Remainder omitted
    }

    用靜態(tài)方法返回,而不是直接返回一個(gè)實(shí)例.

    如果對(duì)對(duì)象序列化,要做多一點(diǎn)工作.如
    To make a singleton class serializable (Chapter 10), it is not sufficient merely to add
    implements Serializable to its declaration. To maintain the singleton guarantee, you must
    also provide a readResolve method (Item 57). Otherwise, each deserialization of a serialized instance will result in the creation of a new instance, 否則,經(jīng)過(guò)對(duì)象反序列化后,會(huì)導(dǎo)致創(chuàng)建了一個(gè)新的對(duì)象.leading, in the case of our example, to spurious Elvis sightings. To prevent this, add the following readResolve method to the Elvis class:
    // readResolve method to preserve singleton property
    private Object readResolve() throws ObjectStreamException {
    /*
    * Return the one true Elvis and let the garbage collector
    * take care of the Elvis impersonator.
    */
    return INSTANCE;
    }

    posted @ 2006-03-30 17:24 dodoma 閱讀(244) | 評(píng)論 (0)編輯 收藏

    Consider providing static factory methods instead of
    constructors 考慮以靜態(tài)工廠方法取代構(gòu)造函數(shù)

    The normal way for a class to allow a client to obtain an instance is to provide a public
    constructor.

    A class can provide a public static factory method, which is simply
    a static method that returns an instance of the class

    such as
    public static Boolean valueOf(boolean b) {
    return (b ? Boolean.TRUE : Boolean.FALSE);
    }

    advantages
    1:One advantage of static factory methods is that, unlike constructors, they have names.
    一個(gè)類靜態(tài)工廠方法是有名字的.If the parameters to a constructor do not, in and of themselves, describe the object being returned, a static factory with a well-chosen name can make a class easier to use and the resulting client code easier to read. 如BigInteger(int, int,Random)只知道new了一個(gè)BigInteger對(duì)象,而BigInteger.probablePrime()能說(shuō)明返回的可能是一個(gè)素?cái)?shù)對(duì)象.另外,如果一個(gè)構(gòu)造函數(shù)僅僅由于參數(shù)順序不同而意思也不同.靜態(tài)工廠方法就更加有用了.它更能說(shuō)明函數(shù)的意思.因?yàn)樗幸粋€(gè)名字.
    the reason?are : If the parameters to a constructor do not, describe the object being
    returned, a static factory with a well-chosen name can make a class easier to use and the
    resulting client code easier to read.

    2:A second advantage of static factory methods is that, unlike constructors, they are not
    required to create a new object each time they're invoked.每次請(qǐng)求時(shí),不需要重新創(chuàng)建一個(gè)對(duì)象----單例的意思.這可以在任何時(shí)刻控制這個(gè)對(duì)象,同時(shí)在比較的時(shí)候也不需要用equals而用= =就可以解決了.

    3:A third advantage of static factory methods is that, unlike constructors, they can return
    an object of any subtype of their return type.可以返回一個(gè)原返回類型的子類型對(duì)象.
    One application of this flexibility is that an API can return objects without making their
    classes public.Hiding implementation classes in this fashion can lead to a very compact API.這種靈活性的一個(gè)應(yīng)用是,一個(gè)A P I可以返回一個(gè)對(duì)象,同時(shí)又不使該對(duì)象的類成為公有的。以這種方式把具體的實(shí)現(xiàn)類隱藏起來(lái),可以得到一個(gè)非常簡(jiǎn)潔的A P I。這項(xiàng)技術(shù)非常適合
    于基于接口的框架結(jié)構(gòu),因?yàn)樵谶@樣的框架結(jié)構(gòu)中,接口成為靜態(tài)工廠方法的自然返回類型
    sample:
    // Provider framework sketch
    public abstract class Foo {
    // Maps String key to corresponding Class object
    private static Map implementations = null;
    // Initializes implementations map the first time it's called
    private static synchronized void initMapIfNecessary() {
    if (implementations == null) {
    implementations = new HashMap();
    // Load implementation class names and keys from
    // Properties file, translate names into Class
    // objects using Class.forName and store mappings.
    ...
    }
    }
    public static Foo getInstance(String key) {
    initMapIfNecessary();
    Class c = (Class) implementations.get(key);
    if (c == null)
    return new DefaultFoo();
    try {
    return (Foo) c.newInstance();
    } catch (Exception e) {
    return new DefaultFoo();
    }
    }
    }

    公有的靜態(tài)工廠方法所返回的對(duì)象的類不僅可以是非公有的,而且該類可以隨著每次調(diào)用
    而發(fā)生變化,這取決于靜態(tài)工廠方法的參數(shù)值。只要是已聲明的返回類型的子類型,都是允
    許的。而且,為了增強(qiáng)軟件的可維護(hù)性,返回對(duì)象的類也可以隨著不同的發(fā)行版本而不同。
    disadvantages:

    1:The main disadvantage of static factory methods is that classes without public or protected constructors cannot be subclassed.
    類如果不含公有的或者受保護(hù)的構(gòu)造函數(shù),就不能被子類化。對(duì)于公有的靜態(tài)工廠所返回的非公有類,也同樣如此

    2:A second disadvantage of static factory methods is that they are not readily distinguishable from other static methods.


    In summary, static factory methods and public constructors both have their uses, and it pays to understand their relative merits. Avoid the reflex to provide constructors without first considering static factories because static factories are often more appropriate. If you've weighed the two options and nothing pushes you strongly in either direction, it's probably best to provide a constructor simply because it's the norm.




    posted @ 2006-03-30 17:08 dodoma 閱讀(220) | 評(píng)論 (0)編輯 收藏

    接口修改為
    package net.blogjava.dodoma.spring.aop;

    public interface HelloI {
    ?public String sayHello(String firstName,String lastName)throws Exception;
    ?}

    類修改為
    package net.blogjava.dodoma.spring.aop;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;

    public class Hello implements HelloI {
    ?protected static final Log log=LogFactory.getLog(Hello.class);
    ?private String msg;
    ?public Hello(){}
    ?public Hello(String msg){
    ??this.msg=msg;
    ?}
    ?
    ?public String getMsg() {
    ??return msg;
    ?}
    ?public void setMsg(String msg) {
    ??this.msg = msg;
    ?}
    ?public String sayHello(String firstName, String lastName) throws Exception{
    ??// TODO Auto-generated method stub
    ??log.info("in the class "+this.getClass().getName()+"'s method sayHello()");
    ? throw new Exception("here is a exception !");
    ??return (msg+" "+firstName+" "+lastName);
    ?}
    }



    package net.blogjava.dodoma.spring.aop;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.aop.ThrowsAdvice;

    public class LogThrowAdvice implements ThrowsAdvice {
    ?protected static final Log log = LogFactory.getLog(LogThrowAdvice.class);
    ?public void afterThrowing(Exception e)throws Throwable{
    ??log.info("in the class "+this.getClass().getName()+"'s method afterThrowing()");
    ??log.info("the exception is "+e.getMessage());
    ?}
    }


    package net.blogjava.dodoma.spring.aop;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.aop.framework.ProxyFactory;
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.beans.factory.xml.XmlBeanFactory;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.core.io.Resource;

    public class HelloTest {
    ?protected static final Log log = LogFactory.getLog(HelloTest.class);

    ?/**
    ? * @param args
    ? * @throws Exception
    ? */
    ?public static void main(String[] args) throws Exception {
    ??// TODO Auto-generated method stub
    ??Resource rs = new ClassPathResource("beans.xml");
    ??BeanFactory bf = new XmlBeanFactory(rs);

    ??HelloI h = (HelloI) bf.getBean("theBean");
    ??log.info("starting...");
    ??try {
    ???log.info(h.sayHello("ma", "bin"));
    ??} catch (Exception e) {
    ???e.printStackTrace();
    ??}
    ??log.info("end...");
    ??
    ??
    ??ProxyFactory factory=new ProxyFactory();
    ??factory.addAdvice(new LogThrowAdvice ());
    ??factory.setTarget(new Hello("hello"));
    ??try{
    ??HelloI hi=(HelloI)factory.getProxy();
    ??hi.sayHello("ma","bin");}
    ??catch(Exception e){e.printStackTrace();}
    ?}

    }

    posted @ 2006-03-28 12:57 dodoma 閱讀(245) | 評(píng)論 (0)編輯 收藏

    LogAroundAdvice 通知
    package net.blogjava.dodoma.spring.aop;

    import org.aopalliance.intercept.MethodInterceptor;
    import org.aopalliance.intercept.MethodInvocation;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;

    public class LogAroundAdvice implements MethodInterceptor {
    ?protected static final Log log = LogFactory.getLog(LogAroundAdvice.class);

    ?public Object invoke(MethodInvocation arg) throws Throwable {
    ??//?調(diào)用目標(biāo)對(duì)象之前
    ??log.info("before the target object");
    ??Object val=arg.proceed();
    ? //調(diào)用目標(biāo)對(duì)象之后
    ??log.info("the arg is "+arg);
    ??log.info("after the target object");
    ??return val;
    ?}

    }

    測(cè)試方法

    package net.blogjava.dodoma.spring.aop;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.aop.framework.ProxyFactory;
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.beans.factory.xml.XmlBeanFactory;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.core.io.Resource;

    public class HelloTest {
    ?protected static final Log log = LogFactory.getLog(HelloTest.class);

    ?/**
    ? * @param args
    ? * @throws Exception
    ? */
    ?public static void main(String[] args) throws Exception {
    ??// TODO Auto-generated method stub
    ??Resource rs = new ClassPathResource("beans.xml");
    ??BeanFactory bf = new XmlBeanFactory(rs);

    ??HelloI h = (HelloI) bf.getBean("theBean");
    ??log.info("starting...");
    ??try {
    ???log.info(h.sayHello("ma", "bin"));
    ??} catch (Exception e) {
    ???e.printStackTrace();
    ??}
    ??log.info("end...");
    ??
    ??
    ??ProxyFactory factory=new ProxyFactory();
    ??factory.addAdvice(new LogAroundAdvice ());
    ??factory.setTarget(new Hello("hello"));
    ??try{
    ??HelloI hi=(HelloI)factory.getProxy();
    ??hi.sayHello("ma","bin");}
    ??catch(Exception e){e.printStackTrace();}
    ?}

    }

    posted @ 2006-03-28 12:52 dodoma 閱讀(281) | 評(píng)論 (1)編輯 收藏

    接口和實(shí)現(xiàn)類見(jiàn)LogBeforeAdvice的例子
    package net.blogjava.dodoma.spring.aop;

    import java.lang.reflect.Method;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.aop.AfterReturningAdvice;

    public class LogAfterAdvice implements AfterReturningAdvice {
    ?protected static final Log log = LogFactory.getLog(LogAfterAdvice.class);
    ?public void afterReturning(Object returnVal, Method m, Object[] args,
    ???Object target) throws Throwable {
    ??// TODO Auto-generated method stub
    ??log.info("in the class "+this.getClass().getName()+"'s method afterReturning()");

    ??log.info("the target class is:" + target.getClass().getName());
    ??log.info("the target method is:" + m.getName());

    ??for (int i = 0; i < args.length; i++) {
    ???log.info("the method's args is:" + args[i]);
    ??}
    ??
    ??log.info("the returnValue is "+returnVal);
    ??//測(cè)試,如果返回裝備發(fā)生了異常.將如何處理程序流程
    ??//throw new Exception("返回裝備發(fā)生異常");
    ?}

    }

    測(cè)試代碼

    package net.blogjava.dodoma.spring.aop;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.aop.framework.ProxyFactory;
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.beans.factory.xml.XmlBeanFactory;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.core.io.Resource;

    public class HelloTest {
    ?protected static final Log log = LogFactory.getLog(HelloTest.class);

    ?/**
    ? * @param args
    ? * @throws Exception
    ? */
    ?public static void main(String[] args) throws Exception {
    ??// TODO Auto-generated method stub
    ??Resource rs = new ClassPathResource("beans.xml");
    ??BeanFactory bf = new XmlBeanFactory(rs);

    ??HelloI h = (HelloI) bf.getBean("theBean");
    ??log.info("starting...");
    ??try {
    ???log.info(h.sayHello("ma", "bin"));
    ??} catch (Exception e) {
    ???e.printStackTrace();
    ??}
    ??log.info("end...");
    ??
    ??
    ??ProxyFactory factory=new ProxyFactory();
    ??factory.addAdvice(new LogAfterAdvice());
    ??factory.setTarget(new Hello("hello"));
    ??try{
    ??HelloI hi=(HelloI)factory.getProxy();
    ??hi.sayHello("ma","bin");}
    ??catch(Exception e){e.printStackTrace();}
    ?}

    }


    在beans.xml中加入如下代碼
    <bean id="theLogAfterAdvice" class="net.blogjava.dodoma.spring.aop.LogAfterAdvice"/>

    <property name="interceptorNames">
    ????? <list>
    ??????? <value>theLogAfterAdvice</value><!--此時(shí)直接使用advice,表明這個(gè)類所有的實(shí)例,方法,都享受advice的攔截-->
    ?????? </list>?
    </property>

    切入點(diǎn)可省略,如需要的話


    <!--切入點(diǎn)-->
    ? <!--Note: An advisor assembles pointcut and advice-->
    ? <bean id="theBeAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
    ??? <property name="advice">
    ????? <ref local="theLogAfterAdvice"/>
    ??? </property>
    ??? <!--匹配模式-->
    ??? <property name="pattern">
    ????? <value>.*</value>
    ??? </property>
    ? </bean>

    posted @ 2006-03-28 12:37 dodoma 閱讀(411) | 評(píng)論 (0)編輯 收藏

    接口
    package net.blogjava.dodoma.spring.aop;

    public interface HelloI {
    ?public String sayHello(String firstName,String lastName);
    ?}

    實(shí)現(xiàn)類
    package net.blogjava.dodoma.spring.aop;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;

    public class Hello implements HelloI {
    ?protected static final Log log=LogFactory.getLog(Hello.class);
    ?private String msg;
    ?public Hello(){}
    ?public Hello(String msg){
    ??this.msg=msg;
    ?}
    ?public String getMsg() {
    ??return msg;
    ?}
    ?public void setMsg(String msg) {
    ??this.msg = msg;
    ?}
    ?public String sayHello(String firstName, String lastName) {
    ??// TODO Auto-generated method stub
    ??log.info("in the class "+this.getClass().getName()+"'s method sayHello()");
    ??return (msg+" "+firstName+" "+lastName);
    ?}
    }

    BeforeAdvice通知

    package net.blogjava.dodoma.spring.aop;

    import java.lang.reflect.Method;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.aop.MethodBeforeAdvice;

    /**
    ?* 方法調(diào)用之前.
    ?* 先調(diào)用此方法
    ?* @author dodoma
    ?**/
    public class LogBeforeAdvice implements MethodBeforeAdvice {
    ?protected static final Log log = LogFactory.getLog(LogBeforeAdvice.class);

    ?public void before(Method m, Object[] args, Object target) throws Throwable {
    ??log.info("in the class "+this.getClass().getName()+"'s method before()");

    ??log.info("the target class is:" + target.getClass().getName());
    ??log.info("the target method is:" + m.getName());

    ??for (int i = 0; i < args.length; i++) {
    ???log.info("the method's args is:" + args[i]);
    ??}
    ??//測(cè)試,如果在before通知中發(fā)生了異常,程序流程將如何
    ??//throw new Exception("異常");
    ?}
    }

    測(cè)試類
    package net.blogjava.dodoma.spring.aop;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.aop.framework.ProxyFactory;
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.beans.factory.xml.XmlBeanFactory;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.core.io.Resource;

    public class HelloTest {
    ?protected static final Log log = LogFactory.getLog(HelloTest.class);
    ?public static void main(String[] args) throws Exception {
    ??// TODO Auto-generated method stub
    ?//應(yīng)用spring的ioc容器
    ??Resource rs = new ClassPathResource("beans.xml");
    ??BeanFactory bf = new XmlBeanFactory(rs);

    ??HelloI h = (HelloI) bf.getBean("theBean");
    ??log.info("starting...");
    ??try {
    ???log.info(h.sayHello("ma", "bin"));
    ?????} catch (Exception e) {
    ???e.printStackTrace();
    ??}
    ??log.info("end...");
    ??
    ??//如果沒(méi)有使用spring的ioc,可以直接用如下代碼測(cè)試
    ??ProxyFactory factory=new ProxyFactory();
    ??factory.addAdvice(new LogBeforeAdvice());//添加通知
    ??factory.setTarget(new Hello("hello"));//添加被代理的類實(shí)例
    ??try{
    ??HelloI hi=(HelloI)factory.getProxy();
    ??hi.sayHello("ma","bin");}
    ??catch(Exception e){e.printStackTrace();}
    ?}

    }

    spring的配置文件beans.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "

    <beans>

    <!--享受日志的類-->
    <bean id="theTargetBean" class="net.blogjava.dodoma.spring.aop.Hello">
    ?<property name="msg">
    ??? ?<value>hello</value>
    ??? </property>
    ?????
    </bean>

    <!--advices-->
    <bean id="theLogBeforeAdvice" class="net.blogjava.dodoma.spring.aop.LogBeforeAdvice"/>

    <!--CONFIG-->
    ? <bean id="theBean" class="org.springframework.aop.framework.ProxyFactoryBean">
    ??? <!--接口-->
    ??? <property name="proxyInterfaces">
    ????? <value>net.blogjava.dodoma.spring.aop.HelloI</value>
    ??? </property>
    ??? <!--被代理的類-->
    ??? <property name="target">
    ????? <ref local="theTargetBean"/>
    ??? </property>
    ??? <!--加在代理類上的advice-->
    ??? <property name="interceptorNames">
    ????? <list>
    ??????? <value>theLogBeforeAdvice</value><!--此時(shí)直接使用advice,表明這個(gè)類所有的實(shí)例,方法,都享受advice的攔截-->
    ??????</list>
    ??? </property>
    ? </bean>
    ??
    ? <!--切入點(diǎn),可以精確匹配類,方法,也可以不需要這個(gè)-->
    ? <!--Note: An advisor assembles pointcut and advice-->
    ? <bean id="theBeAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
    ??? <property name="advice">
    ????? <ref local="theLogBeforeAdvice"/>
    ??? </property>
    ??? <!--匹配模式-->
    ??? <property name="pattern">
    ????? <value>.*</value>
    ??? </property>
    ? </bean>
    ?? ?
    </beans>

    僅列出標(biāo)題  
    主站蜘蛛池模板: 国产精品爱啪在线线免费观看| 亚洲综合免费视频| 在线天堂免费观看.WWW| 在线免费播放一级毛片| 曰批免费视频播放免费| 亚洲午夜精品一区二区麻豆| 久久久久亚洲AV片无码下载蜜桃| 亚洲一级特黄大片在线观看| 日本免费人成黄页网观看视频| 91成年人免费视频| 无码国产精品一区二区免费模式| 一级一黄在线观看视频免费| 最新亚洲人成网站在线观看| 亚洲人成色777777老人头| 国产日本亚洲一区二区三区| 亚洲电影免费观看| 亚洲日本一区二区| 久久精品国产亚洲麻豆| 亚洲熟女少妇一区二区| 亚洲国产av无码精品| mm1313亚洲国产精品美女| 日韩高清在线高清免费| 成人国产mv免费视频| 四色在线精品免费观看| 永久在线毛片免费观看| 成人毛片18女人毛片免费| 免费精品人在线二线三线区别| 免费观看无遮挡www的小视频| 麻花传媒剧在线mv免费观看| 67194国产精品免费观看| 久久精品毛片免费观看| 毛片免费全部播放无码| 很黄很黄的网站免费的| 国产成人免费高清激情明星| 97在线观看永久免费视频| 男女免费观看在线爽爽爽视频| 99xxoo视频在线永久免费观看| 8x8x华人永久免费视频| 0588影视手机免费看片| 久久99九九国产免费看小说| 噼里啪啦免费观看高清动漫4|