spring AOP 拦截器实现问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring AOP 拦截器实现问题相关的知识,希望对你有一定的参考价值。

自学AOP拦截器,遇到点问题。如果在调用一个方法之前拦截这个方法并记录下来,需要实现beforeMethod什么接口,然后还需要在ApplicationContext.xml里进行配置,相关配置文件较多,拦截的方法多需要配置的也就越多,听说可以用注释的方法实现,但不知道怎么注释,求高手指点

创建拦截类:
@Aspect
public class MyAspect
    
     /** 执行前拦截 */
@Before("execution(* t.t..service.*Service.*(..))")
public void before(JoinPoint point) throws Throwable 
System.out.println("执行方法:" + point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName());


/** 执行后拦截 */
@After("execution(* t.t..service.*Service.*(..))")
public void after(JoinPoint point) throws Throwable 
System.out.println("执行完成:" + point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName());


/** 执行前后拦截(环绕) */
@Around("execution(* cn.cydl.dlj..service.*Service.*(..))")
public Object around(ProceedingJoinPoint point) throws Throwable 
System.out.println("执行前...");
// 这里相当于@Before
Object obj = point.proceed();// 调用方法具体执行过程,如果不调用,这原来的方法就不会执行了
// obj问原来的方法返回值,如果不返回obj,则原来的方法即时有return也不会返回任何值
// 这里相当于@After
System.out.println("执行后...");
return obj;

 

applicationContext.xml中
引入AOP支持(头部,请自行补完整,这里不能写html地址):
xmlns:aop="...ingframework.org/schema/aop" 

xsi:schemaLocation="...
...ingframework.org/schema/aop
...ingframework.org/schema/aop/spring-aop-3.2.xsd
"

具体AOP配置:
<!-- AOP配置 -->
<aop:aspectj-autoproxy />
<!-- 指定AOP拦截的Bean(主动指定上面的类) -->
<bean class="t.t.t.MyAspect" />

 

需要Spring核心、SpringAOP和aspectjrt、aspectjweaver等包支持。

参考技术A 方法
方法
方法

spring aop无法拦截类内部的方法调用

1.概念

拦截器的实现原理就是动态代理,实现AOP机制。Spring 的代理实现有两种:一是基于 JDK Dynamic Proxy 技术而实现的;二是基于 CGLIB 技术而实现的。如果目标对象实现了接口,在默认情况下Spring会采用JDK的动态代理实现AOP

2.问题

在类C中,方法A调用方法B,

B方法被AOP拦截。(可能是方法B上在另外的@Aspect切面定义上了切点/也可能是加了@Transactional事务注解,底层原理也是AOP实现),最终A-》B ,B并不会触发AOP。

3.解决方案

1.手动获取代理对象

1.将当前的代理类暴露给线程使用,以下2种自己选一个实现即可。

注解实现方案:springboot:启动类上加注解:@EnableAspectJAutoProxy(exposeProxy=true):

配置实现方案:<aop:aspectj-autoproxy expose-proxy="true" />

2.A中调用B:不要直接用this(因为this是目标对象,自然无法实现代理类的增强方法@before等),而是先去尝试获取代理类:UserServiceImpl service = AopContext.currentProxy() != null ? (UserService)AopContext.currentProxy() : this;

2.去除AOP切面增强,把切面方法单独封装接口方法,在需要的地方调用

 

以上是关于spring AOP 拦截器实现问题的主要内容,如果未能解决你的问题,请参考以下文章

Spring aop 拦截不到Dao

Spring技术内幕:Spring AOP的实现原理

Spring AOP源码分析(拦截器调用的实现)

spring aop无法拦截类内部的方法调用

struts2的拦截器跟spring2 AOP有啥区别?哪个好?

Spring AOP