淺談Spring靜態切入點使用方法

所謂spring靜態切入點,相對於動態切入點來說,具有良好的性能,因爲靜態切入點只在代理創建時候執行一次,而不是在運行期間,每次目標方法執行前都進行執行,下面,以實例說明如何定義靜態切入點

 

看我我前一篇blog的朋友都知道,如果不定義切入點,通知方法是會對整個目標類的所有方法均進行切入的
但實際需求中,我們可能對其中的幾個方法執行A通知,對其他的方法執行B通知,這時候,就需要通過定義不同的切入點來進行區分

目標接口:

 

package StaticAdvisorTest;

public interface Shopping {
  
public String buySomething(String type);
  
public String buyAnything(String type);
  
public String sellSomething(String type);
  
public String sellAnything(String type);

}

 javabean:

 

package StaticAdvisorTest;

public class Customer {
  
private String name;
  
private String age;
  
public Customer(){
      
  }

  
public Customer(String name,String age){
      
this.name=name;
      
this.age=age;
  }

public String getAge() {
    
return age;
}

public void setAge(String age) {
    
this.age = age;
}

public String getName() {
    
return name;
}

public void setName(String name) {
    
this.name = name;
}

}

 

業務目標實現類:

 

package StaticAdvisorTest;

public class ShoppingImpl implements Shopping {
    
private Customer customer;
    
public Customer getCustomer() {
        
return customer;
    }

    
public void setCustomer(Customer customer) {
        
this.customer = customer;
    }

    
public String buySomething(String type) {
        System.out.println(
this.getCustomer().getName()+" bye "+type+" success");
        
return null;
    }

    
    
public String buyAnything(String type) {
       System.out.println(
this.getCustomer().getName()+" bye "+type+" success");
       
return null;

     }

    
public String sellAnything(String type) {
        System.out.println(
this.getCustomer().getName()+" sell "+type+" success");
        
return null;
    }

    
public String sellSomething(String type) {
         System.out.println(
this.getCustomer().getName()+" sell "+type+" success");
           
return null;
    }


}

 

通知(切面)方法:

 

package StaticAdvisorTest;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;
//前置通知
public class WelcomeAdvice implements MethodBeforeAdvice {

    
public void before(Method method, Object[] args, Object obj)
            
throws Throwable {
        String type
=(String)args[0];
        System.out.println(
"Hello welcome to buy "+type);

    }


}

 

下面是重點,我們想對所有的buy方法進行通知處理,也就是在所有的buy方法上定義切面

spring爲我們創建了靜態切入點的父類 StaticMethodMatcherPointCut ,如果我們想實現自制的靜態切入點,只要繼承這個類就可以了,不過一般情況下,我們使用spring提供的靜態切入點NameMatchMethodPointCut就足夠了

配置文件如下:

 

<?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="customer" class="StaticAdvisorTest.Customer">
   
<constructor-arg index="0">
     
<value>gaoxiang</value>
   
</constructor-arg>
    
<constructor-arg index="1">
     
<value>26</value>
   
</constructor-arg>
 
</bean>
 
<bean id="shoppingImpl" class="StaticAdvisorTest.ShoppingImpl">
   
<property name="customer">
     
<ref local="customer"/>
   
</property>
 
</bean>
<!-- 定義通知 -->
<bean id="shoppingAdvise" class="StaticAdvisorTest.WelcomeAdvice"></bean>
<!-- 定義切入點 -->
<bean id="shoppingPointCutAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
  
<property name="mappedName">
    
<value>sell*</value>
  
</property>
  
<property name="advice">
    
<ref bean="shoppingAdvise"/>
  
</property>
</bean>
<!-- 定義代理 -->
<bean id="StaticAdvisorTest" class="org.springframework.aop.framework.ProxyFactoryBean">
  
<property name="proxyInterfaces">
    
<value>StaticAdvisorTest.Shopping</value>
  
</property>
  
<property name="interceptorNames">
    
<list>
      
<value>shoppingPointCutAdvisor</value>
    
</list>
  
</property>
  
<property name="target">
    
<ref bean="shoppingImpl"/>
  
</property>
</bean>

</beans>

 <!-- 如果不使用通配符,則用以下表達 
  <property name="mappedNames">
    <list>
       <value>sellSomething</value>
       <value>sellAnything</value>
    </list>
  </property>
  -->

測試程序:

 

package StaticAdvisorTest;

import java.io.File;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;



public class TestAdvisor {

    
public static void main(String[] args) {

        String filePath
=System.getProperty("user.dir")+File.separator+"StaticAdvisorTest"+File.separator+"hello.xml";
        
        BeanFactory factory
=new XmlBeanFactory(new FileSystemResource(filePath));
        
        Shopping shopping
=null;

        shopping
=(Shopping)factory.getBean("StaticAdvisorTest");
        shopping.buySomething(
"something");
        shopping.buyAnything(
"anything");
        shopping.sellAnything(
"anything");
        shopping.sellSomething(
"something");
        
    

    }

}

 

運行結果:

gaoxiang bye something success
gaoxiang bye anything success
Hello welcome to buy anything
gaoxiang sell anything success
Hello welcome to buy something
gaoxiang sell something success

可以看到,爲所有的sell開頭的方法都進行了切面處理,而sell方法沒有任何影響


轉載地址:http://blog.csdn.net/daryl715/article/details/1618292

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章