JAVA Spring AOP分析与自定义

AOP 也叫面向切片 我们都熟知OOP面向对象,oop主要是封装继承多态,取得了巨大的成功,

而aop则是把系统分解,往里面插入编织的网,中,在spring boot中一个很成功的切面就是@Transactional   能直接了当的实现事务功能,

aop织入方法有3种 本质上就是一个动态代理

  1. 编译期:在编译时,由编译器把切面调用编译进字节码,这种方式需要定义新的关键字并扩展编译器,AspectJ就扩展了Java编译器,使用关键字aspect来实现织入;
  2. 类加载器:在目标类被装载到JVM时,通过一个特殊的类加载器,对目标类的字节码重新“增强”;
  3. 运行期:目标对象和切面都是普通Java类,通过JVM的动态代理功能或者第三方库实现运行期动态织入。

 aop核心概念

  • Aspect:切面,即一个横跨多个核心逻辑的功能,或者称之为系统关注点;
  • Joinpoint:连接点,即定义在应用程序流程的何处插入切面的执行;
  • Pointcut:切入点,即一组连接点的集合;
  • Advice:增强,指特定连接点上执行的动作;
  • Introduction:引介,指为一个已有的Java对象动态地增加新的接口;
  • Weaving:织入,指将切面整合到程序的执行流程中;
  • Interceptor:拦截器,是一种实现增强的方式;
  • Target Object:目标对象,即真正执行业务的核心逻辑对象;
  • AOP Proxy:AOP代理,是客户端持有的增强后的对象引用。

接下来我们来自定义一个注解

1.首先创建一个注解类

/**
 *
 * 自定义注解
 * 注解的声明:public @interface 注解名称
 *
 * 元注解:标记注解的注解
 * @Documented:表示该注解会被javadoc命令写入api文档中
 * @Target:注解的标记位置
 *  ElementType.ANNOTATION_TYPE:该注解可以标记别的注解
 *  ElementType.CONSTRUCTOR:标注到构造方法
 *  ElementType.FIELD:标注到成员属性
 *  ElementType.LOCAL_VARIABLE:标注到局部变量
 *  ElementType.METHOD:标注到方法上
 *  ElementType.PACKAGE:标注到包上
 *  ElementType.PARAMETER:标注到方法形参上
 *  ElementType.TYPE:标注到类、接口、枚举类上
 * @Retention:注解的作用范围
 *  RetentionPolicy.SOURCE:注解的有效范围只在源码中,编译后就被丢弃
 *  RetentionPolicy.CLASS:注解有效范围在编译文件中,运行时丢弃
 *  RetentionPolicy.RUNTIME:注解在运行时仍然有效,这个范围的注解可以通过反射获取
 *
 * 注解内的方法声明:
 * 类型 方法名() [defualt 默认值];
 *
 * 注意:
 * 如果一个属性没有设置default默认值,在标记这个注解时,必须给定该属性值
 * 如果一个属性的名字为value,则在赋值时可以省略属性名。当如果需要赋值两个以上的属性,则value不能省略
 * 如果一个属性的类型是数组类型,则应该用{}赋值,如果只要给一个值,{}可以省略


/**
 * @author Bruce
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Cs {
    boolean data () default false;
}

2.我们来创建一个切片@Aspect

package com.example.demo.config;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

/**
 * @author Bruce
 */
@Component
@Aspect
public class Csa {
    @Around(value="execution(* *..*Controller.*(..)) && @annotation(cs)")
    public Object check(ProceedingJoinPoint pjp,Cs cs) throws Throwable {
        System.out.println(cs.data());
        Object ret = pjp.proceed();
        long begin = System.currentTimeMillis();
        String method = pjp.getSignature().getName();
        String className = pjp.getTarget().getClass().getName();
        log.info("Aspect = [{}] ,class [{}] , method [{}] , time consuming[{}]", new Date(), className, method, System.currentTimeMillis() - begin);
        return ret;
    }
}

这样就能控制到所有的带cs注释的controller

3.给controller添加注释


    /**
     * 测试
     * */
    @Cs
    @RequestMapping(value="/userTest", method = RequestMethod.GET)
    public String test() {
        return IdGenerator.getNextId().toString();
    }

一个简单的自定义注解就完成了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值