Spring mvc项目自定义注解实现拦截器和aop实现日志打印



文章目录

  • Spring mvc项目自定义注解实现拦截器和aop实现日志打印
  • 一、自定义注解实现拦截器
  • 1.新建注解类
  • 2.新建一个类,实现HandlerInterceptor接口和方法
  • 3.spring-mvc.xml文件添加拦截器配置
  • 4.将自定义的注解添加到相应控制器中
  • 二、aop实现日志打印
  • 1.导入切面需要的依赖包
  • 2.新建注解类
  • 3.新建切面类
  • 4.开启aop:aspectj-autoproxy的xml配置
  • 5.将自定义的注解添加到相应控制器中
  • 三、知识点详解
  • 1.自定义注解
  • 2.AOP
  • 3.expression指示符
  • 四、应用场景
  • 总结



一、自定义注解实现拦截器

1.新建注解类

// 登录时做拦截
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginInterceptor {

}

2.新建一个类,实现HandlerInterceptor接口和方法

/**
 *自定义拦截器
 *实现HandlerInterceptor接口
 **/
@Component
public class SourceAccessInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("进入拦截器了");
        // 反射获取方法上的LoginInterceptor注解
        HandlerMethod handlerMethod = (HandlerMethod)handler;
        LoginInterceptor loginInterceptor = handlerMethod.getMethod().getAnnotation(LoginInterceptor.class);
        if(loginInterceptor == null){
            return true;
        }
        // 有LoginInterceptor注解说明需要登录,提示用户登录
        response.setContentType("application/json; charset=utf-8");
        response.getWriter().print("你访问的资源需要登录再访问");
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

3.spring-mvc.xml文件添加拦截器配置

<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="cn.tangtj.clouddisk.security.SourceAccessInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

java自带的注解拦截器 @annotation 拦截类注解_spring

< bean>中添加的是自定义的拦截器类的目录,spring项目必须要添加xml的配置。

spring-boot项目就可以用@Configuration注解加配置类代替xml配置

例如创建一个类,实现WebMvcConfigurer接口,将自定义拦截器添加到MVC中即可

@Configuration
public class MyConfig implements WebMvcConfigurer {
    public void addInterceptors(InterceptorRegistry registry){
        System.out.println("拦截全部");
        // 使拦截器生效 1.此处参数是我们自定义的拦截器名( SourceAccessInterceptor )
        // 2.添加拦截规则(/**)拦截全部
        registry.addInterceptor(new SourceAccessInterceptor()).addPathPatterns("/**");
        WebMvcConfigurer.super.addInterceptors(registry);
    }
}

4.将自定义的注解添加到相应控制器中

二、aop实现日志打印

将核心业务代码和非核心代码分开,非核心代码抽离出来放到代理对象中,然后通过代理对象访问核心业务的方法,既解耦又方便维护非核心代码。

关注点:横切、前置通知、后置通知、返回通知

1.导入切面需要的依赖包

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.4</version>
        </dependency>

2.新建注解类

@Target(ElementType.METHOD) // 作用于方法
@Retention(RetentionPolicy.RUNTIME)
public @interface LogPrint {
    String module() default "";
}

3.新建切面类

@Aspect // 1.切面类注解
public class MyLogAspect {
    private static Logger logger = LogManager.getLogger(MyLogAspect.class.getName());
    // 2. PointCut表示这是一个切点,@annotation表示这个切点切到一个注解上,后面带该注解的全类名
    // @Pointcut("execution(public * *(..))") execution:匹配指定方法。
    // 切面最主要的就是切点,所有的故事都围绕切点发生
    @Pointcut("execution(* cn.tangtj.clouddisk.web.LoginController.*(..))")
    public void controllerPoint() {

    }

    // 环绕通知
    @Around("controllerPoint()")
    public Object log(JoinPoint joinPoint) {
        System.out.println("进aop了 Around");
        String className = joinPoint.getSignature().getDeclaringType().getSimpleName();
        String methodName = joinPoint.getSignature().getName();
        // 打印到控制台,
        logger.info("请求类:{},请求方法:{}", className, methodName);
        return null;
    }
}

4.开启aop:aspectj-autoproxy的xml配置

<bean id="myLogAspect" class="cn.tangtj.clouddisk.annotation.MyLogAspect"></bean>
    <!--开启注解支持: JDK(默认proxy-target-class="false") 
    cglib库(AOP proxy就是target object被增强后的对象,
    在Spring AOP中是通过JDK动态代理或者CGLIB代理技术实现的。)-->
    <aop:aspectj-autoproxy proxy-target-class="false"></aop:aspectj-autoproxy>

5.将自定义的注解添加到相应控制器中

三、知识点详解

1.自定义注解

java自带的注解拦截器 @annotation 拦截类注解_java_02

2.AOP

缩写:Aspect-oriented Programming

目的:对具有横切性质的业务逻辑进行集中处理,典型的应用就是Spring中的事务管理功能。

实现理解:
在Spring中,可以用注解@Aspect定义一个类为一个切面,也可以采用XML的形式定义一个类为切面。在切面类中我们需要定义pointcut(切入点),advice(通知)。Spring会在符合pointcut定义的join point(连接点)处应用advice。

3.expression指示符

execution:匹配指定。

execution(public * *(..))	//任意public方法
execution(* set*(..))	//任意名称以set开头的方法
execution(* com.xyz.service.AccountService.*(..))	//com.xyz.service.AccountService接口中定义的任意方法
execution(* com.xyz.service.*.*(..))	//com.xyz.service包中定义的任意方法
execution(* com.xyz.service..*.*(..))	//com.xyz.service包中及其子包中定义的任意方法

@annotation:注解类指定。

// @annotation表示这个切点切到一个注解上,后面带该注解的全类名
@Pointcut("@annotation(me.zebin.demo.annotationdemo.aoplog.MyLog)")
public void logPointCut(){};

其他指定方法参考

四、应用场景

java自带的注解拦截器 @annotation 拦截类注解_拦截器_03


总结

以上就是今天要讲的内容,本文仅仅简单介绍了Spring mvc项目自定义注解实现拦截器和aop实现日志打印,有描述错误的地方请指出,感谢观看。