Spring AOP模块

说明

AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的另一个重要特征。AOP把一个业务流程分成几部分,例如权限检查、业务处理、日志记录,每个部分单独处理,然后将他们组装成完整的业务流程。每个部分被称为切面(Aspect)或者关注点。

AOP的相关概念

  • 切面Aspect:在本例中,方法withAop()、withoutAop()中都有一些代码。虽然只是一些输出语句,但在真实的程序中这里应该是一些有意义的代码(如读写数据库、权限检查、异常情况记录等)。这些代码可以看做AOP中的切面,可以将切面理解成模块。
  • 通知Advisor:本例的三个拦截器都是实现至某个Advisor接口。从类名上看就知道3个拦截器都是AOP中的通知(Advisor)。一旦Spring符合条件,就会派发出通知。与生活中的通知不同的是,Spring中的通知是带有执行代码的,能实现某种功能。
  • 切入点Pointcut:在配置拦截器的时候,XML中只配置了withAop()方法使用拦截器,而withoutAop()方法没有配置拦截器。这种配置是借助org.springframework.aop.support.NameMatchMethodPointcutAdvisor完成的。从类名称上看,这是一个切入点(Pointcut)。该类对象能配置对哪些方法使用拦截器,从哪个地方切入进去。配置时可以使用通配符。
    即可看成是切入点负责往什么地方插入代码,而通知负责插入什么代码。

实例:使用拦截器拦截方法

Service接口

package interf;

public interface IAopService {
	public void withAop() throws Exception;
	public void withOutAop() throws Exception;
}

接口实现代码

package example;

import javax.security.auth.login.AccountException;

import interf.IAopService;

public class AopService implements IAopService {
	private String name;
	
	@Override
	public void withAop() throws Exception {
		// TODO Auto-generated method stub
		System.out.print("有AOP的函数运行");
		System.out.println("name为:"+name);
		if(name.trim().length()==0)	//检查name是否为空
			throw new AccountException();	//抛出异常
	}

	@Override
	public void withOutAop() throws Exception {
		// TODO Auto-generated method stub
		System.out.print("没有AOP的函数运行");
	}

	public String getName() {
		return name;
	}

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

}

方法前拦截器检查name是否为null

package before;

import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;

import example.AopService;

public class IAopMethodBefore implements MethodBeforeAdvice {

	@Override
	public void before(Method method, Object[] args, Object obj) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("运行前检查...");				//输出信息
		System.out.println("即将执行的Method:"+method.getName());	//输出方法名
		if(obj instanceof AopService){		//instance关键字判断是不是AOPService类
			String name=((AopService) obj).getName();
			if(name==null) throw new NullPointerException();	//检查是否为NULL
		}
		System.out.println("Object:"+obj);				//输出对象
	}

}

返回后拦截器输出返回值

package after;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

public class IAopMethodAfter implements AfterReturningAdvice {

	@Override
	public void afterReturning(Object value, Method method, Object[] args, Object obj) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("方法名:"+method.getName()+"返回值为:"+value);
	}

}

异常拦截器捕获异常

package exception;

import java.lang.reflect.Method;

import javax.security.auth.login.AccountException;

import org.springframework.aop.ThrowsAdvice;

public class ThrowsInterceptor implements ThrowsAdvice{	//异常捕获器
	//方法一
	public void afterThrowing(Method method,Object[] args,Object obj,AccountException ex) throws Throwable{
		System.out.println("方法:"+method+"抛出了异常:"+ex);
	}
	//方法二
	public void afterThrowing(NullPointerException ex) throws Throwable{
		System.out.println("空指针异常:抛出了异常:"+ex);
	}
}
拦截器配置

ApplicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans 
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
	
	<!-- 拦截器 在withAop()方法前运行 安装到NameMatchMethodPointcutAdvice中 -->
	<bean id="aopMethodBefore" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
		<property name="advice">
			<bean class="before.IAopMethodBefore"></bean>
		</property>
		<property name="mappedName" value="withAop"></property>
	</bean>
	
	<!-- 拦截器 在withAop()方法后运行 安装到NameMatchMethodPointcutAdvice中 -->
	<bean id="aopMethodAfter" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
		<property name="advice">
			<bean class="after.IAopMethodAfter"></bean>
		</property>
		<property name="mappedName" value="withAop"></property>
	</bean>
	
	<!-- 拦截器 在异常抛出后运行 安装到NameMatchMethodPointcutAdvice中 -->
	<bean id="aopException" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
		<property name="advice">
			<bean class="exception.ThrowsInterceptor"></bean>
		</property>
		<property name="mappedName" value="withAop"></property>
	</bean>
	
	<!-- Service对象 安装到ProxyFactoryBean对象中 -->
	<bean id="aopService" class="org.springframework.aop.framework.ProxyFactoryBean">
		<!-- 多个拦截器 -->
		<property name="interceptorNames">
			<list>
				<value>aopMethodBefore</value>
				<value>aopMethodAfter</value>
				<value>aopException</value>
			</list>
		</property>
		<!-- 被拦截的对象 -->
		<property name="target">
			<bean class="example.AopService">
				<property name="name" value="HelloMyQiu"></property>
			</bean>
		</property>
	</bean>
</beans>

运行代码

package example;

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;

import interf.IAopService;

public class AopRun {

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		DefaultListableBeanFactory beanFactory=new DefaultListableBeanFactory();
		XmlBeanDefinitionReader reader=new XmlBeanDefinitionReader(beanFactory);
		reader.loadBeanDefinitions(new ClassPathResource("ApplicationContext.xml"));
		
		IAopService service=(IAopService) beanFactory.getBean("aopService");
		service.withAop();
		service.withOutAop();
		
		beanFactory.destroySingletons(); 	//销毁对象
	}

}

结果贴图


总结

拦截器与Filter的区别

二者都是AOP编程思想的体现,都能实现权限检查、日志记录等。

Filter是Servlet规范规定的,只能用于Web程序中,而拦截器还能用于Swing、Application程序中。规范不同,Servlet容器和Spring容器支持,拦截器能使用Spring里任何资源,Filter只能在Servlet前后起作用,而拦截器能深入方法前后、异常前后等。所以在Spring下尽量能使用拦截器就不用Filter

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值