您的位置:首页 > 编程语言 > Java开发

SpringAop_各种通知

2015-11-05 01:04 513 查看
切面:

package com.spring.aop.xml;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

/**
* 切面
*/
public class Transaction {

/*
* 前置通知:
*       在目标方法执行之前
*
*     参数:joinpoint 连接点(客户端调用那个方法,那个方法就是连接点)
*
*/
public void beginTransaction(JoinPoint joinpoint){

//连接点的名称
String methodName = joinpoint.getSignature().getName();
System.out.println("连接点名称: "+methodName);

//目标类
System.out.println("目标类 : "+ joinpoint.getTarget().getClass());

System.out.println("beginTransaction ");
}

/**
*
* 后置通知
*         在目标方法执行之后
*         可以获取目标方法的返回值
*
*     参数Object的名称要和 配置文件中的returning 保持一致
*
*/
public void commit(JoinPoint joinPoint,Object val){

System.out.println("目标方法的返回值: "+val);

System.out.println("commit transaction ");

}

/**
* 最终通知:
*         无论目标方法抛出异常都将执行
*
*
*/
public void finallyMethod(){

System.out.println("finally method");
}

/**
* 异常通知:
*         接收目标方法抛出的异常
*
*/

public void throwingMethod(JoinPoint joinPoint,Throwable ex){

System.out.println("发生异常了 信息:"+ex.getMessage());

}

/**
* 环绕通知
* joinPoint.proceed(); 如果在环绕通知中不写,则目标方法不再执行
*     也就是说环绕通知可以控制目标方法的执行
*
*
*/
public void aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable{

System.out.println("aaaaaa");
joinPoint.proceed(); //调用目标方法

}

}


目标类:

package com.spring.aop.xml;

public interface PersonDao {
public String savePerson();

}


package com.spring.aop.xml;

public class PersonDaoImpl implements PersonDao {

@Override
public String savePerson() {

//        int i=1/0;

System.out.println("save person !");

return "saveok";
}

}


ApplicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
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 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> 
<!-- 加入aop的命名空间
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation= http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
-->

<bean  id="personDao" class="com.spring.aop.xml.PersonDaoImpl"></bean>
<bean  id="transaction" class="com.spring.aop.xml.Transaction"></bean>

<aop:config>

<!--
切入点表达式 :确定目标类

-->
<aop:pointcut expression="execution(* com.spring.aop.xml.PersonDaoImpl.*(..) )" id="perform"/>

<!--

切面:
ref 指向切面
-->
<aop:aspect ref="transaction">

<!--
前置通知:
1.在目标方法执行之前
2.获取不到目标方法的返回值

-->
<!--                         <aop:before method="beginTransaction" pointcut-ref="perform"/> -->

<!--
后置通知:
1.后置通知可以获取目标方法的返回值
2.当目标方法抛出异常,后置通知将不再执行
returning="val" 用于获取目标类的返回值,该名称要和方法参数名称一致

-->
<!--                         <aop:after-returning method="commit" pointcut-ref="perform"  returning="val"/> -->

<!--
最终通知:
无论目标方法抛出异常都将执行

-->
<aop:after method="finallyMethod" pointcut-ref="perform"/>

<!--
异常通知:
throwing的名称和通知的参数名称保持一致

-->

<aop:after-throwing method="throwingMethod" pointcut-ref="perform" throwing="ex"/>

<!--
环绕通知:
能控制目标方法的执行
前置通和后置通知能在目标方法的前面和后面加一些代码,但是不能控制目标方法的执行

-->

<aop:around method="aroundMethod" pointcut-ref="perform"/>

</aop:aspect>
</aop:config>

</beans>


测试代码

package com.spring.aop.xml;

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

/*
* 原理:
1.当Spring容器启动的时候,加载两个bean,对两个bean进行实列化
2.当Spring容器对应的配置文件解析到<aop:config>的时候
3.把切入点表达式解析出来,按照切入点表达式匹配spring容器内容的bean
4.如果匹配成功,则为该bean创建代理对象
5.当客户端利用context.getBean获取一个对象时,如果该对应有代理对象,则返回代理对象
如果没有代理对象,则返回对象本身

*
*
*/

public class TransactionTest {

@Test
public void testTransaction(){

ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");

PersonDao personDao = (PersonDao) context.getBean("personDao");
personDao.savePerson();

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: