声明:本博文用于学习总结及工作心得
项目中需要修改IM信息送以及短信发送,要求已离职的人员不呢收到IM信息和短信
因为在项目中各个地方都有使用到短信和IM信息通知;所以想到使用Spring AOP进行实现,以及拦截器进行实现,一下为两种方法的具体实现代码:
1)Spsing AOP
ppackage com.xxx.utils; import com.xxx.bean_new.personnel.Employee; import com.xxx.bean_new.personnel.User; import com.xxx.dao_new.EmployeeDAO; import com.xxx.dao_new.UserDAO; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; /** * Created by Administrator on 2016/11/4 0004. */ //声明这是一个切面Bean @Aspect public class SendMsgAspect { @Before("execution(* com.xxx.pushMsg.PushMsg.sendMsg(..))") Object before(JoinPoint joinPoint) { Object[] args = joinPoint.getArgs(); try { if (args.length >= 2) { String IMAccount = (String) args[2]; UserDAO userDAO = (UserDAO) Utils.getBean("userDAO"); if (null != userDAO) { User user = userDAO.getUsersByIMAccount(IMAccount); if (null != user) { EmployeeDAO employeeDAO = (EmployeeDAO) Utils.getBean("employeeDAO"); Employee employee = employeeDAO.get(user.getEmployeeId()); //这里进行业务逻辑判断 通过IMAcount信息获取到员工,如果该员工状态为离职,则将IMAcount修改空也就是args[2];并且抛出异常 由try{}catch捕捉该异常 //否则不做任何操作,直接返回 if (employee == null || employee.getEntry() == null || employee.getEntry().getStatus() == null || "离职".equals(employee.getEntry().getStatus())) { args[2] = ""; throw new RuntimeException(employee.getName() + ":该员工已离职通知失败!"); } } } } } catch (Exception e) { //扑捉到异常后 pjp.proceed(args)将args 也就是修改后的参数传给目标函数 这里的目标函数是指被切入点的函数 //需要注意的是,如果是使用了pjp.proceed(args) 目标函数会被执行两次 正是因为这点 所以接着写了另一个具有相同功能的拦截器 ProceedingJoinPoint pjp = (ProceedingJoinPoint) joinPoint; Object retVal = null; try { retVal = pjp.proceed(args); } catch (Throwable throwable) { throwable.printStackTrace(); } return retVal; } return null; } } |
配置文件中添加以下内容: <bean id="sendMsgAop" class="com.xxx.utils.SendMsgAspect"> </bean> <aop:config> <!-- 定义切点 --> <aop:pointcut id="aroundPointcutTarget" expression="execution(* com.xxx.pushMsg.PushMsg.sendMsg(..))"/> <!-- 定义切面 --> <aop:aspect id="userAspect" ref="sendMsgAop"> <!--通知函数 method 的参数为 ProceedingJoinPoint 类型 该类型为 JoinPoint 的子类 可以通过该对象获取 被切面参数 以及 返回值--> <aop:before method="before" pointcut-ref="aroundPointcutTarget"/> <!--<aop:around method="checkEntrystatus" pointcut-ref="aroundPointcutTarget"/>--> </aop:aspect> </aop:config> |
2)MethodInterceptor拦截器
package com.xxx.utils; import com.xxx.bean_new.personnel.Employee; import com.xxx.bean_new.personnel.User; import com.xxx.dao_new.EmployeeDAO; import com.xxx.dao_new.UserDAO; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import java.lang.reflect.Method; /** * Created by Administrator on 2016/11/5 0005. */ public class SendMsgInterceptor implements MethodInterceptor { @Override public Object invoke(MethodInvocation invo) throws Throwable { Object[] args = invo.getArguments(); Method method = invo.getMethod(); if (!"sendMsg".equals(method.getName())) { Object obj = invo.proceed(); return obj; } try { if (args.length >= 2) { String IMAccount = (String) args[2]; UserDAO userDAO = (UserDAO) Utils.getBean("userDAO"); if (null != userDAO) { User user = userDAO.getUsersByIMAccount(IMAccount); if (null != user) { EmployeeDAO employeeDAO = (EmployeeDAO) Utils.getBean("employeeDAO"); Employee employee = employeeDAO.get(user.getEmployeeId()); //业务逻辑判断 通过IMAcount信息获取到员工,如果该员工状态不为离职的情况下,通过 invo.proceed();它来对目标对象方法调用,返回一个Object对象。 //否则不做任何操作,直接返回 if (employee != null && employee.getEntry() != null && employee.getEntry().getStatus() != null && !"".equals(employee.getEntry().getStatus())) { Object obj = invo.proceed(); return obj; } } } } } catch (Exception e) { e.printStackTrace(); } return args; } } |
<bean id="myInterceptor" class="com.xxx.utils.SendMsgInterceptor" abstract="false" lazy-init="default" autowire="default"> </bean> <!--这里需要注意如果是使用接口的话 这里需要这样定义--> <!--<bean id="bean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>aop.Interface</value> </property> <property name="interceptorNames"> <list> <value>myInterceptor</value> </list> </property> </bean>--> <!--方法--> <!--<bean class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">--> <!--<property name="mappedNames">--> <!--<list>--> <!--<value>send*</value><!– 所有方法 –>--> <!--</list>--> <!--</property>--> <!--<property name="advice">--> <!--<ref local="myInterceptor"/>--> <!--</property>--> <!--</bean>--> <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames"> <!--PushMsg类可以使用注解 或者手动加入到配置文件--> <list><value>pushMsg</value></list> </property> <property name="interceptorNames"> <list> <value>myInterceptor</value> </list> </property> </bean> |
第二种不会造成目标函数第二次执行