Spring AOP


AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的一个重要特征
Spring推荐使用接口编程
Spring提供三种拦截器:方法前拦截器、返回后拦截器、异常抛出拦截器

拦截器定义

  1. //Service接口  
  2. public interface IAopService{  
  3.     public void withAop() throws Exception;         //将会被拦截  
  4.     public void withoutAop() throws Exception;      //不会被拦截  
  5. }  
  6.   
  7. public class AopServiceImpl implements IAopService{  
  8.     private String name;  
  9.     public void withAop() throws Exception{  
  10.         System.out.println("有AOP的函数运行。name:"+name);  
  11.         if(name.trim().length() == 0){  
  12.             throw new AccountException("name属性不能为空");  
  13.         }  
  14.     }  
  15.   
  16.     public void withoutAop() throws Exception{  
  17.             System.out.println("没有AOP的函数运行。");  
  18.     }  
  19.   
  20.     public void setName(String name){  
  21.         this.name = name;  
  22.     }  
  23.   
  24.     public String getName(){  
  25.         return this.name;  
  26.     }  
  27. }  
//Service接口
public interface IAopService{
	public void withAop() throws Exception;			//将会被拦截
	public void withoutAop() throws Exception;		//不会被拦截
}

public class AopServiceImpl implements IAopService{
	private String name;
	public void withAop() throws Exception{
		System.out.println("有AOP的函数运行。name:"+name);
		if(name.trim().length() == 0){
			throw new AccountException("name属性不能为空");
		}
	}

	public void withoutAop() throws Exception{
			System.out.println("没有AOP的函数运行。");
	}

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

	public String getName(){
		return this.name;
	}
}


  1. //方法前拦截器,检查name是否为空  
  2. import  org.springframework.aop.MethodBeforeAdvice;  
  3. public class MethodBeforeInterceptor implements MethodBeforeAdvice{  
  4.     //调用对象的方法前执行该方法  
  5.     //参数分别为被调用的方法、被调用方法的参数、对象  
  6.     public void before(Method method,Object [] args,Object instance) throws Throwable{  
  7.         System.out.println("即将执行方法:"+method.getName());  
  8.         //  
  9.         if(instance instanceof AopServiceImpl){  
  10.             String name = ((AopServiceImpl)instance).getName();  
  11.             if(name == null){  
  12.                 throw new NullPointerException("name不能为空");  
  13.             }  
  14.         }  
  15.     }  
  16.           
  17. }  
//方法前拦截器,检查name是否为空
import  org.springframework.aop.MethodBeforeAdvice;
public class MethodBeforeInterceptor implements MethodBeforeAdvice{
	//调用对象的方法前执行该方法
	//参数分别为被调用的方法、被调用方法的参数、对象
	public void before(Method method,Object [] args,Object instance) throws Throwable{
		System.out.println("即将执行方法:"+method.getName());
		//
		if(instance instanceof AopServiceImpl){
			String name = ((AopServiceImpl)instance).getName();
			if(name == null){
				throw new NullPointerException("name不能为空");
			}
		}
	}
		
}


  1. //返回后拦截器  
  2. import  org.springframework.aop.AfterReturningAdvice;  
  3. public class MethodAfterInteceptor implements AfterReturningAdvice{  
  4.     //参数分别为方法返回值、被调用方法、方法参数、被拦截的对象  
  5.     public void afterReturning(Object value,Method method,Object [] args,Object instance) throws Throwable{  
  6.                 System.out.println("方法:"+method.getName()+"执行完毕,返回值为:"+value);  
  7.     }  
  8.       
  9. }  
//返回后拦截器
import  org.springframework.aop.AfterReturningAdvice;
public class MethodAfterInteceptor implements AfterReturningAdvice{
	//参数分别为方法返回值、被调用方法、方法参数、被拦截的对象
	public void afterReturning(Object value,Method method,Object [] args,Object instance) throws Throwable{
				System.out.println("方法:"+method.getName()+"执行完毕,返回值为:"+value);
	}
	
}


  1. //异常拦截器捕获异常  
  2. import  org.springframework.aop.ThrowAdvice;  
  3. public class ThrowsInterceptor implements ThrowAdvice{  
  4.     //参数分别为被调用的方法、方法参数、对象实例、抛出的异常  
  5.     //前三个参数可以省略,第四个参数是必须的,这样设计是为了使开发者灵活地定义多个方法捕获各种不同的异常  
  6.     public void afterThrowing(Method method,Object [] args,Object instance,AccountException ex) throws Throwable {  
  7.         System.out.println("方法:"+method.getName()+"抛出了异常:"+ex);  
  8.     }  
  9.   
  10.     public void afterThrowing(NullPointerException ex) throws Throwable {  
  11.         System.out.println("抛出了异常:"+ex);  
  12.     }  
  13.   
  14. }  
//异常拦截器捕获异常
import  org.springframework.aop.ThrowAdvice;
public class ThrowsInterceptor implements ThrowAdvice{
	//参数分别为被调用的方法、方法参数、对象实例、抛出的异常
	//前三个参数可以省略,第四个参数是必须的,这样设计是为了使开发者灵活地定义多个方法捕获各种不同的异常
	public void afterThrowing(Method method,Object [] args,Object instance,AccountException ex) throws Throwable {
		System.out.println("方法:"+method.getName()+"抛出了异常:"+ex);
	}

	public void afterThrowing(NullPointerException ex) throws Throwable {
		System.out.println("抛出了异常:"+ex);
	}

}


拦截器配置

Spring无法将Service的实现类与拦截器直接组装,因为没有对应的setter、getter方法。安装时借助的是Spring的代理类,把拦截器安装到NameMatchMethodPointcutAdvisor中,把自动以的Service安装到ProxyFactoryBean中,然后组装到一块

  1. <!-- 方法前拦截器MethodBeforeInterceptor安装到NameMatchMethodPointcutAdvisor中 -->  
  2. <bean id="aopMethodBeforeInterceptor" class="org.springframework.aop.support. NameMatchMethodPointcutAdvisor">  
  3.     <!--  拦截器的实现类-->  
  4.     <property name="advice">  
  5.         <bean class="com.clf.spring. MethodBeforeInterceptor">  
  6.     </property>  
  7.     <!--  欲拦截的方法名-->  
  8.     <property name="mappedName" value="withAop">  </property>  
  9. </bean>  
  10.   
  11. <!-- 类似的方式配置返回后前拦截器MethodAfterInteceptor -->  
  12. <bean id="aopMethodAfterInterceptor" class="org.springframework.aop.support. NameMatchMethodPointcutAdvisor">  
  13.     <property name="advice">  
  14.         <bean class="com.clf.spring. MethodAfterInteceptor">  
  15.     </property>  
  16.     <property name="mappedName" value="withAop">  </property>  
  17. </bean>  
  18.   
  19. <!-- 类似的方式配置异常前拦截器MethodAfterInteceptor -->  
  20. <bean id="aopThrowsInterceptor" class="org.springframework.aop.support. NameMatchMethodPointcutAdvisor">  
  21.     <property name="advice">  
  22.         <bean class="com.clf.spring. ThrowsInterceptor">  
  23.     </property>  
  24.     <property name="mappedName" value="withoutAop">   </property>  
  25. </bean>  
  26.   
  27. <!-- Service实现类,安装到ProxyFactoryBean -->  
  28. <bean id="aopService" class="org.springframework.aop.ProxyFactoryBean">  
  29.     <!-- 安装拦截器-->  
  30.     <property name="interceptorNames">  
  31.         <list>  
  32.             <value>aopMethodBeforeInterceptor</value>  
  33.             <value>aopMethodAfterInterceptor</value>  
  34.             <value>aopThrowsInterceptor</value>  
  35.         </list>  
  36.     </property>  
  37.     <!—被拦截的对象-->  
  38.     <property name="target">  
  39.         <bean class="com.clf.spring.AopServiceImpl">  
  40.             <property name="name" value="HelloSpring"></property>  
  41.         </bean>  
  42.     </property>  
  43. </bean>  
<!-- 方法前拦截器MethodBeforeInterceptor安装到NameMatchMethodPointcutAdvisor中 -->
<bean id="aopMethodBeforeInterceptor" class="org.springframework.aop.support. NameMatchMethodPointcutAdvisor">
	<!--  拦截器的实现类-->
	<property name="advice">
		<bean class="com.clf.spring. MethodBeforeInterceptor">
	</property>
	<!--  欲拦截的方法名-->
	<property name="mappedName" value="withAop"> 	</property>
</bean>

<!-- 类似的方式配置返回后前拦截器MethodAfterInteceptor -->
<bean id="aopMethodAfterInterceptor" class="org.springframework.aop.support. NameMatchMethodPointcutAdvisor">
	<property name="advice">
		<bean class="com.clf.spring. MethodAfterInteceptor">
	</property>
	<property name="mappedName" value="withAop"> 	</property>
</bean>

<!-- 类似的方式配置异常前拦截器MethodAfterInteceptor -->
<bean id="aopThrowsInterceptor" class="org.springframework.aop.support. NameMatchMethodPointcutAdvisor">
	<property name="advice">
		<bean class="com.clf.spring. ThrowsInterceptor">
	</property>
	<property name="mappedName" value="withoutAop"> 	</property>
</bean>

<!-- Service实现类,安装到ProxyFactoryBean -->
<bean id="aopService" class="org.springframework.aop.ProxyFactoryBean">
	<!-- 安装拦截器-->
	<property name="interceptorNames">
		<list>
			<value>aopMethodBeforeInterceptor</value>
			<value>aopMethodAfterInterceptor</value>
			<value>aopThrowsInterceptor</value>
		</list>
	</property>
	<!—被拦截的对象-->
	<property name="target">
		<bean class="com.clf.spring.AopServiceImpl">
			<property name="name" value="HelloSpring"></property>
		</bean>
	</property>
</bean>


AOP相关概念

切面Aspect
在本例中,方法withAop()、withoutAop()中都有一些代码,这些代码可以看做是AOP中的切面,可以将切面理解为模块
通知Advisor
本例的三个拦截器都是实现自某个接口,从类名上看就知道三个拦截器都是AOP中的通知。一旦Spring符合条件,就会派发出通知,即一些需要执行的代码,能实现某种功能
切入点Pointcut
在配置拦截器时,XML中只配置了withAop()方法使用拦截器,而withoutAop()方法没有配置拦截器,这种配置是借助于org.springframework.aop.support. NameMatchMethodPointcutAdvisor完成的。这就是一个切入点,配置时可以使用通配符。该类明上也带有Advisor是因为它也是用通知实现的

简单地说,切入点负责往什么地方插入代码,而通知负责插入什么代码
Spring提供灵活的切入点配置,例如使用正则表达式
  1. <bean id="advisorTest" class="org.springframework.aop.support.RegexMethodPointcutAdvisor">  
  2.     <property name="interceptor">  
  3.         <ref local="someInterceptor">  
  4.     </property>  
  5.     <property name="pattern">  
  6.         <list>  
  7.             <value>.*get*</value>  
  8.             <value>.*set*</value>  
  9.         </list>  
  10.     </property>  
  11. </bean>  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值