Spring AOP(面向切面编程)【不同类型的Advice】

Spring AOP编程的核心是通过IoC生成代理对象,代理对象的配置通常有如下几个属性:

<property name="interfaces">
</propety>
<property name="targetName">
</property>
<property name="interceptorNames">
</property>

其中,interfaces是目标对象所实现的接口,targetName是目标对象的名字,interceptorNames是Advice或者Advisor的名字。


不同类型的Advice

1、前置通知(before advice)

前置通知需要实现MethodBeforeAdvice接口,并覆盖接口中的如下方法:

void before(Method method,Object[] args,Object target)
该方法将在目标对象的方法调用前被调用。


使用前置通知,需要创建前置通知类,实现MethodBeforeAdvice接口,如下所示:

public class LogBeforeAdvice implements MethodBeforeAdvice {

	@Override
	public void before(Method arg0, Object[] arg1, Object arg2)
			throws Throwable {
		System.out.println("Invoke LogBeforeAdvice.before");
		Logger.log("LogBeforeAdvice:"+arg0.getName());
	}

}
2、后置通知(after advice)

与前置通知对应,Spring框架的AOP组件中提供了后置通知类型。

后置通知在一个方法被调用后执行。后置通知必须实现接口AfterReturningAdvice,并覆盖其中的方法:

void afterReturning(Object return Value,Method method,Object[] args,Object target)
后置通知的实现类如下:

public class LogAfterAdvice implements AfterReturningAdvice {

	@Override
	public void afterReturning(Object arg0, Method arg1, Object[] arg2,
			Object arg3) throws Throwable {
			System.out.println("Invoke LogAfterAdvice.afterReturning");
			Logger.log("LogAfterAdvice: "+arg1.getName()+" return "+arg0);
	}
}

3、环绕通知(around advice)

环绕通知可以再被拦截的方法执行过程的任何一个阶段被调用,也可能由于某种原因,而不调用被拦截的方法,这是前置和后置通知做不到的。

前置和后置通知不能阻止调用被拦截的方法。

环绕通知必须实现MethodInterceptor接口,覆盖接口中的方法:

Objectinvoke (MethodInvocation invocation)
invoke方法的参数类型是MethodInvocation,MethodInvocation类中提供了proceed方法,用来调用被拦截的方法。

如果环绕通知中没有调用proceed方法,则目标方法不被调用。

4、异常通知(exception advice)

异常通知在被拦截的方法抛出异常时调用。

异常通知必须实现ThrowsAdvice接口。

该接口中没有方法,是一个标记接口。实现该接口后,异常通知类可以定义多个方法,方法必须符合如下规范:

afterThrowing([Method],[args],[target],Throwable subclass)
afterThrowing方法的参数Method]、[args]、[target]都是可选项,必须制定的参数是Throwable,即抛出异常的具体类型。

异常通知的实现类如下所示:

public class LogThrwosAdvice implements ThrowsAdvice {

	public void afterThrowing(RegisterException e) {
		System.out.println("Invoke LogThrwosAdvice.afterThrowing");
		Logger.log("LogThrwosAdvice: "+e.getMessage());
	}
	public void faterThrowing(IOException e){
		Logger.log(e.getMessage());
	}

}
上述异常通知中定义了两个方法,方法中指定了不同异常类型的形式参数,分别处理RegisterException和IOException异常,当被拦截的方法抛出了对应类型的异常时,将被异常通知类拦截。


至此,已经学习了Spring框架的AOP组件中常用的四种Advice类型。


总结Advice的使用步骤:

①使用IoC配置Advice

要使用Advice,首先必须在配置文件中使用IoC配置其对应的bean。

	<bean id="logbefore" class="advice.LogBeforeAdvice">
	</bean>
	<bean id="logafter" class="advice.LogAfterAdvice">
	</bean>
	<bean id="logaround" class="advice.LogAroundAdvice">
	</bean>
	<bean id="logthrows" class="advice.LogThrowsAdvice">
	</bean>
②、在代理对象中引用Advice

配置了Advice的bean后,在需要使用Advice的代理对象中,就可以通过引用bean的id值使用Advice。

一个代理对象可以使用多个Advice,同时,一个Advice也可以被多个代理对象使用。

<bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="interfaces">
			<list>
				<value>service.CustomerService</value>
			</list>
		</property>
		<property name="targetName">
			<value>service</value>
		</property>
		<property name="interceptorNames">
			<list>
				<value>logbefore</value>
				<value>logafter</value>
				<value>logaround</value>
				<value>logthrows</value>
			</list>
		</property>
	</bean>

③、测试拦截器的使用

package test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import exception.RegisterException;
import service.CustomerService;
import vo.Customer;

public class TestAdvice {

	public static void main(String[] args) {
		ApplicationContext ctxt= new ClassPathXmlApplicationContext("applicationContext.xml");
		CustomerService serviceProxy = (CustomerService) ctxt.getBean("serviceProxy");
		try {
			serviceProxy.register(new Customer("aom","aom",23,"BJ"));
		} catch (RegisterException e) {
			// TODO Auto-generated catch block
			System.out.println("custname already exist.");
		}
	}

}
当数据库不存在该用户时,register方法不抛出异常,输出结果如下:

Invoke LogBeforeAdvice.before
Invoke LogAroundAdvice.invoke
invoke register...
Invoke LogAfterAdvice.afterReturning
日志文件记录如下信息:

Wed Jul 30 14:44:10 CST 2014: LogBefore: register
Wed Jul 30 14:44:10 CST 2014: LogAroundAdvice :register
Wed Jul 30 14:44:11 CST 2014: LogAfterAdvice: register return null

当再次执行时,此时数据库已存在该用户,将抛出RegisterException,被异常拦截器拦截,输出结果如下:

Invoke LogBeforeAdvice.before
Invoke LogAroundAdvice.invoke
invoke register...
Invoke LogThrwosAdvice.afterThrowing
custname already exist.
日志文件记录如下信息:

Wed Jul 30 14:46:18 CST 2014: LogBefore: register
Wed Jul 30 14:46:18 CST 2014: LogAroundAdvice :register
Wed Jul 30 14:46:19 CST 2014: LogThrowsAdvice: null

执行下面测试代码:

public class TestAdvice {

	public static void main(String[] args) throws RegisterException {
		ApplicationContext ctxt= new ClassPathXmlApplicationContext("applicationContext.xml");
		CustomerService serviceProxy = (CustomerService) ctxt.getBean("serviceProxy");
			serviceProxy.register(new Customer("aom","aom",23,"BJ"));
			System.out.println("main end");

	}

}
上述代码中没有捕获RegisterException异常,而是将异常声明抛出。由于用户名已存在数据库中,执行上述代码将发生异常,

输出结果如下:

Invoke LogBeforeAdvice.before
Invoke LogAroundAdvice.invoke
invoke register...
Invoke LogThrowsAdvice.afterThrowing
Exception in thread "main" exception.RegisterException
	at service.CustomerServiceImpl.register(CustomerServiceImpl.java:31)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
上述代码中发生异常后,并没有被捕获,依然会调用异常通知,

但是“main end”没有被输出,说明异常没有被捕获,main方法中断。

可见,异常通知不是用来捕获异常的,而是用来定义发生异常后需要处理的功能。









  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值