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;
}
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);
}
}
}