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中的异常用
Spring的AOP实现之一 --- 用spring编写Spring通知
最新推荐文章于 2023-03-30 21:08:41 发布