五分钟入门SpringAOP

SpringAOP的使用

SpringAOP、过滤器、拦截器之间的区别

  • 过滤器:拦截web访问url地址,在拦截器之前,对所有的请求起作用。基于函数回调且依赖于servlet容器。
  • 拦截器:拦截web访问url地址,只对controller起作用。基于java的反射机制,使用代理模式。
  • AOP:针对代码的方法级别做拦截。
  • 应用场景:一般情况下请求都需要经过登录校验,首先应该考虑到使用过滤器在最顶层最校验。涉及到日志记录,且要在业务逻辑完成前后做日志记录的时候,可以考虑拦截器,但是拦截器是根据url进行匹配,则不够细致,这次就考虑使用aop来实现,他是根据方法级别做拦截,很适合做日志记录。

AOP术语

  • 连接点(Joinpoint):spring允许你通知的位置,指方法的前或后等。
  • 切点:(PointCut):例如一个方法有十几个类,则连接点就有十几个,但是我只想对某些类进行通知,则就需要通过切点来筛选连接点。
@Pointcut("execution(* cn.text.controller..*.*(..))")
execution(): 表达式主体
第一个* 号位置:表示返回类型,*表示所有的类型
cn.text.controller:表示需要拦截的包名
包名后的点:第一个.表示当前包,第二个点表示当前包的子包
第二个*号位置:表示类名,*号表示所有的类
*(..)*表示所有方法,括号里的点表示参数,两个点表示所有参数。
  • 通知(Advice):指在连接点上需要的功能。
    前置通知(@Before):在执行连接点代码前做的操作。
    后置通知(@After):在执行连接点代码后做的操作。
    异常通知(@AfterThrowing):在执行连接点代码出现异常后做的操作。
    返回通知(@AfterReturning):在执行连接点代码后无异常后做的操作。
    环绕通知(@Around):可以在执行连接点代码前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行。
  • 目标对象(Target):需要被通知的业务对象。
  • 织入(Weaving):将切面内容融入到目标对象来创建新的代理对象的过程。
  • 切面(Aspect):是通知和切入点的结合。
  • 代理(Proxy):AOP框架创建的对象,用于实现切面契约(通知方法执行等功能)。

配置

首先在applicationContext.xml中配置
proxy-target-class属性值决定是基于接口的还是基于类的代理被创建。如果proxy-target-class 属性值被设置为true,那么基于类的代理将起作用(这时需要cglib库)。如果proxy-target-class属值被设置为false或者这个属性被省略,那么标准的JDK 基于接口的代理将起作用。如果目标类没有生命接口,则Spring将自动使用CGLib动态代理。(故proxy-target-class可省略)

<aop:aspectj-autoproxy proxy-target-class="true"/>//启动对@Aspectj的自动代理的支持
<context:component-scan base-package="cn.text.aspect" />//IOC自动扫包

依赖文件

<!-- Spring AOP -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.10</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.3.9.RELEASE</version>
        </dependency>

JoinPoint和ProceedingJoinPoint区别

AspectJ使用org.aspectj.lang.JoinPoint接口表示目标类连接点对象,如果是环绕通知时,使用org.aspectj.lang.ProceedingJoinPoint表示连接点对象,该类是JoinPoint的子接口。
1)JoinPoint
java.lang.Object[] getArgs():获取连接点方法运行时的入参列表;
Signature getSignature() :获取连接点的方法签名对象;
java.lang.Object getTarget() :获取连接点所在的目标对象;
java.lang.Object getThis() :获取代理对象本身;
2)ProceedingJoinPoint
ProceedingJoinPoint继承JoinPoint子接口,它新增了两个用于执行连接点方法的方法:
java.lang.Object proceed() throws java.lang.Throwable:通过反射执行目标对象的连接点处的方法;
java.lang.Object proceed(java.lang.Object[] args) throws java.lang.Throwable:通过反射执行目标对象连接点处的方法,不过使用新的入参替换原来的入参。

实例

@Aspect//把当前类标识为一个切面供容器读取
@Component//把切面类注入到IOC容器中
@Slf4j
public class LogAspect {
    @Pointcut("execution(* cn.text.service..*(..))")
    public void pointCutService(){ }
    @Before("pointCutService()")
    public void ServiceBefore(JoinPoint joinPoint) {
        ServletRequestAttributes requestAttributes =
         (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        log.info("===============请求内容===============");
        log.info("请求地址:" + request.getRequestURL().toString());
        log.info("请求方式:" + request.getMethod());
        log.info("请求类方法:" + joinPoint.getSignature());
        log.info("请求类方法参数:" + Arrays.toString(joinPoint.getArgs()));
        log.info("===============请求内容===============");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值