浅谈Spring静态切入点使用方法

本文介绍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方法没有任何影响

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值