Spring通過一個特殊的方法攔截器接口IntroductionMethodInterceptor來實現引入。這個接口添加一個方法:
boolean implementsInterface(Class intf);
如果IntroductionMethodInterceptor是為了實現指定接口,那么方法implementsInterface應該返回true.就是說,調用這個接口聲明的方法的任何調用將被委派給IntroductionMethodInterceptor的invoke()方法.invoke()方法負責實現這個方法,不能調用MethodInvocation.proceed().他引入了新的接口,調用目標對象是沒有用的。
Spring提供了一個方便的類來處理我們的大多數應用:DelegatingintroductionInterceptor.代碼:
package com.wyq.spring.base.aopinstance;
import java.util.Date;
/**
* @author 作者
* @version 創建時間:2009-11-6 下午02:58:21
* 類說明
*/
public interface Auditable {
void setLastModifiedDate(Date date);
Date getLastModifiedDate();
}
import java.util.Date;
/**
* @author 作者
* @version 創建時間:2009-11-6 下午02:58:21
* 類說明
*/
public interface Auditable {
void setLastModifiedDate(Date date);
Date getLastModifiedDate();
}
package com.wyq.spring.base.aopinstance;
import java.util.Date;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
/**
* @author 作者
* @version 創建時間:2009-11-6 下午03:00:06
* 類說明
*/
public class AuditableMixin extends DelegatingIntroductionInterceptor implements
Auditable {
private Date lastModifiedDate;
/*
* 注意我們不用實現invoke()方法了,DelegatingIntroductionInterceptor為我們實現了這
* 個方法。DelegatingIntroductionInterceptor也要實現你的混合類暴露的任何方法,并且將
* 任何對這些方法的調用委托給這個混合類。因為我們的類實現了Auditable,對這個接口的方法的
* 所有調用都將調用我們的攔截器。任何其他方法將委托給目標對象。
*/
public Date getLastModifiedDate() {
return lastModifiedDate;
}
public void setLastModifiedDate(Date lastModifiedDate) {
this.lastModifiedDate = lastModifiedDate;
}
}
import java.util.Date;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
/**
* @author 作者
* @version 創建時間:2009-11-6 下午03:00:06
* 類說明
*/
public class AuditableMixin extends DelegatingIntroductionInterceptor implements
Auditable {
private Date lastModifiedDate;
/*
* 注意我們不用實現invoke()方法了,DelegatingIntroductionInterceptor為我們實現了這
* 個方法。DelegatingIntroductionInterceptor也要實現你的混合類暴露的任何方法,并且將
* 任何對這些方法的調用委托給這個混合類。因為我們的類實現了Auditable,對這個接口的方法的
* 所有調用都將調用我們的攔截器。任何其他方法將委托給目標對象。
*/
public Date getLastModifiedDate() {
return lastModifiedDate;
}
public void setLastModifiedDate(Date lastModifiedDate) {
this.lastModifiedDate = lastModifiedDate;
}
}
創建一個引入Advisor:
因為引入通知只應用在類層次上,所以引入有他們自己的Advisor:IntroductionAdvisor.Spring也提供了一個適合大多數情況的缺省實現。它的名字叫做DefaultIntroductionAdvisor.
BeanFactory對象是一個負責創建其他JavaBean的JavaBean.我們的ProxyFactoryBean創建代理對象。和其他JavaBean一樣,它有控制行為的屬性。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- 創建一個目標對象 -->
<bean id="courseTarget" class="com.springinaction.training.model.Course"></bean>
<!-- 創建一個引入 -->
<bean id="auditableMixin" class="com.springinaction.training.advice.AuditableMixin"></bean>
<!-- 創建一個引入通知 -->
<bean id="auditableAdvisor" class="org.springframework.aop.support.DefaultIntroductionAdvisor">
<constructor-arg>
<ref bean="auditableMixin"/>
</constructor-arg>
</bean>
<!-- 創建一個代理
ProxyFactoryBean的屬性
target:代理的目標對象
proxyinterfaces:代理應該實現的接口列表
interceptorNames:需要應用到目標對象上的通知Bean的名字,可以是攔截器、Advisor或者其他通知類型的名字。
singleton:在每次抵用getBean時,工廠是否返回的是同一個代理實例。如果是有狀態通知,應該設置為false.
aopProxyFactory:通常不需要使用這個屬性。
ProxyTargetClass:是否代理目標類,而不是接口類。
-->
<bean id="course" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyTargetClass">
<value>true</value>
</property>
<property name="singleton">
<value>false</value>
</property>
<property name="proxyInterfaces">
<value>com.springinaction.training.advice.Auditable</value>
</property>
<property name="interceptorNames">
<ref bean="auditableAdvisor"/>
</property>
<property name="target">
<ref bean="courseTarget"/>
</property>
</bean>
</beans>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- 創建一個目標對象 -->
<bean id="courseTarget" class="com.springinaction.training.model.Course"></bean>
<!-- 創建一個引入 -->
<bean id="auditableMixin" class="com.springinaction.training.advice.AuditableMixin"></bean>
<!-- 創建一個引入通知 -->
<bean id="auditableAdvisor" class="org.springframework.aop.support.DefaultIntroductionAdvisor">
<constructor-arg>
<ref bean="auditableMixin"/>
</constructor-arg>
</bean>
<!-- 創建一個代理
ProxyFactoryBean的屬性
target:代理的目標對象
proxyinterfaces:代理應該實現的接口列表
interceptorNames:需要應用到目標對象上的通知Bean的名字,可以是攔截器、Advisor或者其他通知類型的名字。
singleton:在每次抵用getBean時,工廠是否返回的是同一個代理實例。如果是有狀態通知,應該設置為false.
aopProxyFactory:通常不需要使用這個屬性。
ProxyTargetClass:是否代理目標類,而不是接口類。
-->
<bean id="course" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyTargetClass">
<value>true</value>
</property>
<property name="singleton">
<value>false</value>
</property>
<property name="proxyInterfaces">
<value>com.springinaction.training.advice.Auditable</value>
</property>
<property name="interceptorNames">
<ref bean="auditableAdvisor"/>
</property>
<property name="target">
<ref bean="courseTarget"/>
</property>
</bean>
</beans>