spring系列(五):切面编程(aop)3

开发环境:jdk1.7     spring3.2.2

前两篇文章讲了各种增强处理,这篇文章再接着讲用注解定义增强以及切面编程的具体应用

一   用注解定义增强处理

除了实现Spring提供的特定接口,Spring还通过集成AspectJ实现了以注解的方式定义增强类,

大大减少了配置文件中的工作量。

增强处理代码

package com.obtk.advise;

import java.lang.reflect.Method;
import java.util.Arrays;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

import com.obtk.entitys.UserEntity;

@Aspect
public class AnnotationAdvise {
	private static final Logger log = Logger.getLogger(AnnotationAdvise.class);

	/*
	@Before("execution(* com.obtk.dao.*.saveUser(..))")
	public void beforMeth(JoinPoint jp) {
		log.info("注解定义的前置增强==,调用者:"+jp.getTarget()
				      +",方法名:"+jp.getSignature().getName()
				       +",参数列表:"+Arrays.toString(jp.getArgs()));
	}
	
	@AfterReturning(pointcut="execution(* com.obtk.dao.*.saveUser(..))",returning="returnValue")
	public void afterMeth(JoinPoint jp,Object returnValue){
		log.info("注解定义的后置增强==,调用者:"+jp.getTarget()
				      +",方法名:"+jp.getSignature().getName()
				       +",参数列表:"+Arrays.toString(jp.getArgs())
				       +",返回值:"+returnValue);
	}
	
	@AfterThrowing(pointcut="execution(* com.obtk.dao.*.saveUser(..))",throwing="e")
	public void afterPaoChu(JoinPoint jp,RuntimeException e){
		log.info("注解定义的异常抛出增强==,调用者:"+jp.getTarget()
			      +",方法名:"+jp.getSignature().getName()
			       +",参数列表:"+Arrays.toString(jp.getArgs())
			       +",异常信息===>:"+e);
	}
	*/
	//注解定义环绕增强
	@Around("execution(* com.obtk.dao.*.saveUser(..))")
	public Object arundAdvise(ProceedingJoinPoint jp){
		log.info("注解定义的前置增强==,调用者:"+jp.getTarget()
			      +",方法名:"+jp.getSignature().getName()
			       +",参数列表:"+Arrays.toString(jp.getArgs()));
		Object result=null;
		try {
			result=jp.proceed();
			log.info("注解定义的后置增强==,调用者:"+jp.getTarget()
				      +",方法名:"+jp.getSignature().getName()
				       +",参数列表:"+Arrays.toString(jp.getArgs())
				       +",返回值:"+result);
		} catch (Throwable e) {
			log.info("注解定义的异常抛出增强==,调用者:"+jp.getTarget()
				      +",方法名:"+jp.getSignature().getName()
				       +",参数列表:"+Arrays.toString(jp.getArgs())
				       +",异常信息===>:"+e);
		}
		return result;
	}
}

切入点代码

package com.obtk.dao;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

import com.obtk.entitys.UserEntity;
import com.obtk.utils.MybatisUtil;

public class UserDaoImpl implements IUserDao{
	
	public int saveUser(UserEntity theUser) {
		System.out.println("方法执行前....");
		int result=0;
		SqlSession session=null;
		try {
			//4.得到session
			session=MybatisUtil.getSession();
			//5.执行语句
			result=session.insert("user.saveOne", theUser);
			session.commit();
			//添加完成可以取出启动增长的主键
			System.out.println("添加成功!");
		} catch (Exception e) {
			System.out.println("抛出了异常");
			session.rollback();
			throw new RuntimeException("发生了异常");
		}finally{
			MybatisUtil.closeSession();
		}
		return result;
	}
	
}
配置

<?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:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	                    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	                    http://www.springframework.org/schema/aop
	                    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
	
	<bean id="userDao" class="com.obtk.dao.UserDaoImpl"></bean>
	<!-- 增强处理的代码 -->
	<bean id="aspectBean" class="com.obtk.advise.AnnotationAdvise"></bean>
	
	<!-- 启动增强处理注解的支持 -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>


二  aop具体应用

1.  用环绕增强统一处理事务问题

要切入的代码

package com.obtk.dao;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

import com.obtk.entitys.UserEntity;
import com.obtk.utils.MybatisUtil;

public class UserDaoImpl implements IUserDao {

	public int saveUser(UserEntity theUser) throws RuntimeException{
		// 4.得到session
		SqlSession session = MybatisUtil.getSession();
		System.out.println("程序代码中的对象哈希码:"+session.hashCode());
		// 5.执行语句
		int result = session.insert("user.saveOne", theUser);
		// 添加完成可以取出启动增长的主键
		System.out.println("添加成功!");
		return result;
	}

}
这里没有任何事务及异常处理,统一交给增强处理的代码完成

增强处理的代码如下:

package com.obtk.advise;

import java.lang.reflect.Method;
import java.util.Arrays;

import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

import com.obtk.entitys.UserEntity;
import com.obtk.utils.MybatisUtil;

@Aspect
public class AnnotationAdvise {
	private static final Logger log = Logger.getLogger(AnnotationAdvise.class);

	@Around("execution(* com.obtk.dao.*.saveUser(..))")
	public Object arundAdvise(ProceedingJoinPoint jp){
		Object result=null;
		SqlSession session=MybatisUtil.getSession();
		System.out.println("增强处理的代码对象哈希码:"+session.hashCode());
		try {
			result=jp.proceed();
			session.commit();
		} catch (Throwable e) {
			session.rollback();
			e.printStackTrace();
		}finally{
			MybatisUtil.closeSession();
		}
		return result;
	}
}
配置

<?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:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	                    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	                    http://www.springframework.org/schema/aop
	                    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
	
	<bean id="userDao" class="com.obtk.dao.UserDaoImpl"></bean>
	<!-- 增强处理的代码 -->
	<bean id="aspectBean" class="com.obtk.advise.AnnotationAdvise"></bean>
	
	<!-- 启动增强处理注解的支持 -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

2   转账案例

简单模拟账户表




dao层代码

package com.obtk.dao;

import org.hibernate.Query;
import org.hibernate.Session;

public class AcctDaoImpl implements IAcctDao{
	@Override
	public void doPay(int payId, double amount) throws RuntimeException{
		String hql="update AcctEntity set balance=balance-? where acctId=?";
		Session session=HiberUtil.getSession();
		Query qy=session.createQuery(hql);
		qy.setParameter(0, amount);
		qy.setParameter(1, payId);
		int result=qy.executeUpdate();
		if(result==0){
			throw new RuntimeException("付款失败");
		}
	}
	
	@Override
	public void doReceive(int receiveId, double amount) {
		String hql="update AcctEntity set balance2=balance+? where acctId=?";
		Session session=HiberUtil.getSession();
		Query qy=session.createQuery(hql);
		qy.setParameter(0, amount);
		qy.setParameter(1, receiveId);
		int result=qy.executeUpdate();
		if(result==0){
			throw new RuntimeException("收款失败");
		}
	}
	
}



切入点不能配置在dao层

建立业务层biz

package com.obtk.biz;

import com.obtk.dao.IAcctDao;


public class AcctBiz {
	private IAcctDao acctDao;
	
	public void setAcctDao(IAcctDao acctDao) {
		this.acctDao = acctDao;
	}
	
	//一个业务调用多个dao层的方法
	public void doTransfer(int payId,int receiveId, double amount) throws RuntimeException{
		acctDao.doPay(payId, amount);
		acctDao.doReceive(receiveId, amount);
	}
	
	
}
切入点配置在biz层
package com.obtk.advise;


import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.obtk.dao.HiberUtil;

@Aspect
public class AnnotationAdvise {
	@Around("execution(* com.obtk.biz.*.do*(..))")
	public Object arundAdvise(ProceedingJoinPoint jp){
		Object result=null;
		Session session=HiberUtil.getSession();
		System.out.println("增强处理的代码对象哈希码:"+session.hashCode());
		Transaction tx=null;
		try {
			tx=session.beginTransaction();
			result=jp.proceed();
			tx.commit();
		} catch (Throwable e) {
			System.out.println("我回滚了");
			tx.rollback();
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
		return result;
	}
}
配置

<?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:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	                    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	                    http://www.springframework.org/schema/aop
	                    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
	
	<bean id="userDao" class="com.obtk.dao.UserDaoImpl"></bean>
	<bean id="acctDao" class="com.obtk.dao.AcctDaoImpl"></bean>
	<bean id="acctBiz" class="com.obtk.biz.AcctBiz">
		<property name="acctDao" ref="acctDao"></property>
	</bean>
	<!-- 增强处理的代码 -->
	<bean id="aspectBean" class="com.obtk.advise.AnnotationAdvise"></bean>
	
	<!-- 启动增强处理注解的支持 -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>














  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

御前两把刀刀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值