Spring的AOP实现之一 --- 用spring编写Spring通知

Spring的AOP实现之一 --- 用spring编写Spring通知
创建通知是实现spring的面向切面的关键点之一
创建通知分为环绕通知,前置通知,后置通知,异常通知,我们来一一介绍
1.	Spring都是在service中实现的,为了方便,我们来创建serviceImpl和service
(1)PersonService.java   接口
package cn.csdn.hr.service;
import java.util.Date;
public interface PersonService {
		//学习科目和开始的日期
		public void study(String name,Date startTime);
}	
(2) PersonServiceBean.java  实现类
package cn.csdn.hr.service;
import java.util.Date;
public class PersonServiceBean implements PersonService {

		@Override
		public void study(String name, Date startTime) {
System.out.println("学习的科目为:"+name+"学习的时间为:+"+startTime);
}
2.创建bean.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd ">
</beans>
3.首先来写环绕通知
环绕通知需要继承MethodInterceptor接口并实现接口中的类
package cn.csdn.hr.advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MyAroundAdvice implements MethodInterceptor{
	//创建自己环绕的通知
	@Override
	public Object invoke(MethodInvocation methodInvoaction) throws Throwable {
		
		System.out.println("执行方法之前执行操作");
		//执行目标方法
		Object object = methodInvoaction.proceed();
		System.out.println("执行方法之后执行操作");
		return object;
	}	
}
4.我们要在bean.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

	<!-- 配置环绕通知 -->
	<bean id="myAroundAdvice" class="cn.csdn.hr.advice.MyAroundAdvice"/>
	<!-- 业务bean -->
	<bean id="personServiceBean" class="cn.csdn.hr.service.PersonServiceBean"></bean>

	<!--代理的bean -->
	<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
		<!-- 代理的接口 -->
		<property name="proxyInterfaces">
			<list>
				<value>cn.csdn.hr.service.PersonService</value>
			</list>
		</property>
		
		<!-- 拦截的名称(通知的名称)-->
		<property name="interceptorNames">
			<list>
				<value>myAroundAdvice</value>
			</list>
		</property>
		
		<!-- 执行的目标对象   即为通知的对象-->
		<property name="target">
			<ref bean="personServiceBean"/>
		</property>
	</bean>
</beans>

注:需要注意的是我们要实现一个bean,class为"org.springframework.aop.framework.ProxyFactoryBean"的类做代理的baen来和通知相关联,在属性名为interceptorNames的value中配置指定的通知类的id名,
5.我们来测试一下吧!
public void test() {
		// 获取应用程序上下文对象
		ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");

		PersonService personService =  (PersonService) ac.getBean("proxyFactoryBean");
	
		personService.study("java", new Date());
	}
测试结果为:

执行方法之前执行操作
学习的科目为:java学习的时间为:+Wed Apr 18 08:30:13 GMT 2012
执行方法之后执行操作

一个通知写完之后,剩下的通知也就好说了吧!但需要注入他们继承的接口
1.	前置通知代码   MyBeforeAdvice.java
package cn.csdn.hr.advice;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class MyBeforeAdvice implements MethodBeforeAdvice{
	/**
	 * 第一个参数:方法对象
	 * 第二个参数:方法参数
	 * 第三个对象:目标对象
	 */
	@Override
	public void before(Method method, Object[] args, Object target)
			throws Throwable {
		
		Object obj=null;
		if(args.length>0){
			obj=args[0];
		}
		System.out.println("-----------before-------方法名称:"+method.getName()+"-----第一个参数值----------:"+obj.toString()+"-------目标对象--------:"+obj.getClass());
	}
}

在bean.xml中的配置为:
<!-- 配置前置通知 -->
	<bean id="myBeforeAdvice" class="cn.csdn.hr.advice.MyBeforeAdvice"/>
和
<value>myBeforeAdvice</value>

测试类和以上的一样,测试的结果为:

-----------before-------方法名称:study-----第一个参数值----------:java-------目标对象--------:class java.lang.String
学习的科目为:java学习的时间为:+Wed Apr 18 09:24:47 GMT 2012

2.后置通知  MyAfterAdvice.java
package cn.csdn.hr.advice;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class MyAfterAdvice implements AfterReturningAdvice{
	@Override
	public void afterReturning(Object returnValue, Method method, Object[] args,
			Object target) throws Throwable {
		// 执行目标方法之后执行操作对象
		System.out.println("==========after========方法的返回值:"+returnValue);
		
	}
}


在bean.xml中的配置为:
<!-- 配置后置通知 -->
	<bean id="myAfterAdvice" class="cn.csdn.hr.advice.MyAfterAdvice" />

和<value>myAfterAdvice</value>

测试类和以上的一样,测试的结果为:
学习的科目为:java学习的时间为:+Wed Apr 18 09:26:19 GMT 2012
==========after========方法的返回值:null


3.异常通知 MyThrowsAdvice.java
package cn.csdn.hr.advice;
import java.lang.reflect.Method;
import org.springframework.aop.ThrowsAdvice;
public class MyThrowsAdvice implements ThrowsAdvice{
public void afterThrowing(Method method, Object[] args,Object target,Throwable throwable){
		System.out.println("异常的信息:"+throwable.getMessage());
	}
}

在bean.xml中的配置
<!-- 配置异常通知 -->
	<bean id="myThrowsAdvice" class="cn.csdn.hr.advice.MyThrowsAdvice" />
和
<value>myThrowsAdvice</value>

我们为了测试,可以在PersonServiceBean中写一个异常,为:
Int i = 1/0;

当执行的时候结果为:
学习的科目为:java学习的时间为:+Wed Apr 18 09:28:44 GMT 2012
异常的信息:/ by zero

如果在PersonServiceBean中的异常用



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值