AOP和Interceptor与java注解的结合使用

很多框架都用到了注解,常见的如spring,hibernate,springMvc,SpringBoot等。使用注解有什么用呢?

      注解和xml一样,都能提供元数据的支持,二者都有各自的好吃,但是使用注解会和代码的结合性更密切一些,我认为注解提供元数据的支持,在接口拦截器和AOP等编程方式能很好的在业务中对需求的实现!


注解的知识点可以参考此篇博主的文章:

https://www.cnblogs.com/huajiezh/p/5263849.html

http://www.importnew.com/10294.html


javaEE项目中对项目业务具有横向切割的有2项技术:1.拦截器 2.AOP面向切面变成,后面分别来讲他们是如何与注解一起结合工作的。

一、拦截器与java注解的结合

struts2的拦截和springmvc的拦截原理差不多,在此以springMvc的拦截器为例子:

注解类:

package cn.xdf.dtmanager.system.interceptop;

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;

import java.lang.annotation.*;

/**
 * Created by fengch on 2018/1/9.
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
@Order(Ordered.HIGHEST_PRECEDENCE)
public @interface RequestLimit {
    /**
     * 次数,默认最大
     * @return
     */
    int count() default Integer.MAX_VALUE;

    /**
     * 时长,单位毫秒
     * @return
     */
    long time() default 6000;
}

springMvc拦截器的配置:

<mvc:interceptors>
        <mvc:interceptor>
            <!-- 统计接口时长拦截器 -->
            <mvc:mapping path="/**" />
            <bean class="cn.xdf.dtmanager.system.interceptop.InterceptorTimeCount" />
        </mvc:interceptor>

        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="cn.xdf.dtmanager.system.interceptop.InterceptorTest" />
        </mvc:interceptor>
    </mvc:interceptors>
package cn.xdf.dtmanager.system.interceptop;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;

/**
 * 计算接口访问时长问题
 * Created by fengch on 2017/11/3.
 */
public class InterceptorTest extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            RequestLimit requestLimit = findAnnotation((HandlerMethod) handler, RequestLimit.class);
            if(requestLimit != null) {
                System.out.println(requestLimit.count() + "::::::::" + requestLimit.time());
            } else {
                System.out.println("此Action方法上面有没注解!");
                return true;
            }
        }
        return super.preHandle(request, response, handler);
    }

    private <T extends Annotation> T findAnnotation(HandlerMethod handler, Class<T> annotationType) {
        T annotation = handler.getBeanType().getAnnotation(annotationType);
        if (annotation != null) return annotation;
        return handler.getMethodAnnotation(annotationType);
    }
}

此findAnnotation方法已经封装好了注解类型的获取。通过传入的注解类进行判断是否为null,否则并上是使用了注解。在来看看实际使用注解的Controller:

    @ResponseBody
    @RequestMapping(value = "/test.do")
    @RequestLimit(count = 10, time = 5000L)
    public String test(HttpServletRequest request, HttpServletResponse response) {
        try {
            Boolean b = masterTeacherService.queryMasterTeacherClassRoom("73", "aaaccc", "test");
            System.out.println(b);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("aaaaaaaaaaaaaaaaaa");

        return "aaaaaa" + DateUtil.dateToString(new Date(), DateUtil.DATATIME_FORMMATER);
    }


二、AOP和java注解的结合

AOP可以分为配置文件的方式和注解的方式,由于使用注解是特定的业务进行注解切面拦截,所以后面是以注解的方式配置AOP生效。

spring的配置文件开启AOP注解如下:

    <!-- 启动AspectJ支持 -->
    <aop:aspectj-autoproxy />
注解类:

package cn.xdf.dtmanager.system.interceptop;

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;

import java.lang.annotation.*;

/**
 * Created by fengch on 2018/1/9.
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
@Order(Ordered.HIGHEST_PRECEDENCE)
public @interface RequestLimit {
    /**
     * 次数,默认最大
     * @return
     */
    int count() default Integer.MAX_VALUE;

    /**
     * 时长,单位毫秒
     * @return
     */
    long time() default 6000;
}

AOP类:

package cn.xdf.dtmanager.system.service.impl;

import cn.xdf.dtmanager.system.interceptop.RequestLimit;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

/**
 * Created by fengch on 2018/1/9.
 */

@Component
@Aspect
public class AopAspectTest {

    @Before("execution(* cn.xdf.dtmanager.business.*.service.*.query*(..)) && @annotation(requestLimit)")
    public void aroundAdvice(JoinPoint joinPoint, RequestLimit requestLimit) {
        System.out.println(requestLimit);
        System.out.println("test````````````````````````");
    }
}

注意拦截的是类跟注解同时存在的会被AOP所拦截。


猜你喜欢

转载自blog.csdn.net/fengchao2016/article/details/79015020
今日推荐