1. 程式人生 > >Spring AOP之Introduction(@DeclareParents)簡介(轉)

Spring AOP之Introduction(@DeclareParents)簡介(轉)

Spring的文件上對Introduction這個概念和相關的註解@DeclareParents作了如下介紹:

Introductions (known as inter-type declarations in AspectJ) enable an aspect to declare that advised objects implement a given interface, and to provide an implementation of that interface on behalf of those objects.
An introduction is made using the @DeclareParents annotation. This annotation is used to declare that matching types have a new parent (hence the name).

 

在這段介紹之後還給出了一個例子,對於初學者要理解這段話以及後面的例子還是蠻困難的,因此下面用一個簡單的例子告訴大傢什麼是Introduction以及如何使用@DeclareParents註解。

對於Introduction這個詞,個人認為理解成引入是最合適的,其目標是對於一個已有的類引入新的介面(有人可能會問:有什麼用呢?簡單的說,你可以把當前物件轉型成另一個物件,那麼很顯然,你就可以呼叫另一個物件的方法了),看一個例子就全明白了。

假設已經有一個UserService類提供了儲存User物件的服務,但是現在想增加對User進行驗證的功能,只對通過驗證的User提供儲存服務,在不修改UserService類程式碼的前提下就可以通過Introduction來解決。

首先定義一個Verifier介面,裡面定義了進行驗證的方法validate(),如下所示:

複製程式碼
package com.jackfrued.aop;

import com.jackfrued.models.User;

public interface Verifier {

    public boolean validate(User user);
}
複製程式碼

 

接下來給出該介面的一個實現類BasicVerifier,如下所示:

複製程式碼
package com.jackfrued.aop;

import com.jackfrued.models.User;

public class BasicVerifier implements Verifier {

    @Override
    public boolean validate(User user) {
        if(user.getUsername().equals("jack") && user.getPassword().equals("1234")) {
            return true;
        }
        return false;
    }
}
複製程式碼

如何才能為UserService類增加驗證User的功能呢,如下所示定義Aspect:

複製程式碼
package com.jackfrued.aop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyAspect {
    @DeclareParents(value="com.tsinghuait.services.UserService", 
            defaultImpl=com.tsinghuait.aop.BasicVerifier.class)
    public Verifier verifer;
}
複製程式碼

接下來就可以將UserService物件轉型為Verifier物件並對使用者進行驗證了,如下所示:

複製程式碼
package com.jackfrued.main;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.jackfrued.aop.Verifier;
import com.jackfrued.models.User;
import com.jackfrued.services.Service;

class Test {

    public static void main(String[] args) {
        User user1 = new User();
        user1.setUsername("abc");
        user1.setPassword("def");
        
        ApplicationContext factory = new ClassPathXmlApplicationContext("config.xml");
        Service s = (Service) factory.getBean("service");
        Verifier v = (Verifier) s;
        if(v.validate(user1) {
            System.out.println("驗證成功");
            s.serve(user1);
        }
        
    }
}
複製程式碼

這樣,上面程式碼中的user1是不會被服務的,當然是因為沒有通過驗證啦!

這樣一說,是不是大概明白什麼是Introduction了呢,其實@DeclareParents用起來也很簡單吧!

至於配置檔案和其他內容請參考完整原始碼:/Files/jackfrued/Spring-introduction.rar

 

引自:http://www.blogjava.net/jackfrued/archive/2010/02/27/314060.html