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

Spring AOP及MethodInterceptor拦截器实现方法拦截以及切入点函数阻止执行

2016-11-05 17:31 831 查看
声明:本博文用于学习总结及工作心得

项目中需要修改IM信息送以及短信发送,要求已离职的人员不呢收到IM信息和短信

因为在项目中各个地方都有使用到短信和IM信息通知;所以想到使用Spring AOP进行实现,以及拦截器进行实现,一下为两种方法的具体实现代码:

1)Spsing AOP

需要被织入的切面类:
ppackage com.rhxy.utils;

import com.rhxy.bean_new.personnel.Employee;

import com.rhxy.bean_new.personnel.User;

import com.rhxy.dao_new.EmployeeDAO;

import com.rhxy.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.rhxy.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;

    }

}
applicationContext.xml配置文件修改
配置文件中添加以下内容:

<bean id="sendMsgAop" class="com.rhxy.utils.SendMsgAspect">
</bean>
<aop:config>
<!-- 定义切点 -->
<aop:pointcut id="aroundPointcutTarget"
 expression="execution(* com.rhxy.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.rhxy.utils;

import com.rhxy.bean_new.personnel.Employee;

import com.rhxy.bean_new.personnel.User;

import com.rhxy.dao_new.EmployeeDAO;

import com.rhxy.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.p
4000
roceed();它来对目标对象方法调用,返回一个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;

    }

}
applicationContext.xml配置文件修改
<bean id="myInterceptor"
 class="com.rhxy.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>
第二种不会造成目标函数第二次执行
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  aop Java