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

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

2017-12-23 10:44 507 查看
开发环境: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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: