`
zenghuiss
  • 浏览: 26045 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

同一个类中调用方法spring AOP未被触发

 
阅读更多
前几天部门有个活,需要对一些敏感信息字段进行脱敏,正好团队内部几个系统都有这个需求,
我一想,这不是个很好的应用AOP的场景吗?
正好刚重新温习了遍AOP,应用到实际场景的机会就来了。
撸起袖子,说干就干。
由于需求明确,实现起来很顺利,跑完UT后,结果一片飘绿,非常开心的推荐给相关的几个系统使用,我还得意得沉浸在学以致用的喜悦中没多久,A同学跑过来说,你这个AOP应用不到啊!
简直是当头一棒!
先讲一下我的实现方案:
  • 1. 定义脱敏字段注解,对需要脱敏字段选择合适脱敏方法
  • @Target(value = {ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface MaskFields{
    }
    
  • 2. 定义脱敏方法注协,告诉AOP切面,哪些方法是需要脱敏处理的
  • @Target(value = {ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface MaskMethod{
    }
    

  • 3. 实现脱敏切面
  • @Component
    @Aspect
    public class MaskAop {
        private Logger logger = LoggerFactory.getLogger(getClass());
    
        @Pointcut("@annotation(MaskMethod)")
        public void pointcut() {
        }
    
        // 定义 advise
        @Before("pointcut()")
        public void maskFieldProcess(JoinPoint joinPoint) {
            logger.info("---Before method {} invoke, param: {}---", joinPoint.getSignature().toShortString(), joinPoint.getArgs());
        }
    }


  • 4. 在spring的配置文件中,打开AOP的代理
  • <aop:aspectj-autoproxy/>  
    <aop:aspectj-autoproxy proxy-target-class="true"/>  



    然后我仔细检查了A同学的使用方式,

    @Service
    public class SomeService {
        private Logger logger = LoggerFactory.getLogger(getClass());
    
        public List<UserVo> getUserList(String someParam) {
            List<UserModel> userModelList= userDao.getUsers();
            return modelToVo(userModelList)
        }
    
        @MaskMethod
        public void modelToVo() {
    
        }
    }


    经过debug调试,发现这个方法根本没有被AOP拦截到!查阅资料,发现这算是spring AOP的一个限制. spring AOP 并不是扩展了一个类(目标对象), 而是使用了一个代理对象来包装目标对象, 并拦截目标对象的方法调用. 这样的实现带来的影响是: 在目标对象中调用自己类内部实现的方法时, 这些调用并不会转发到代理对象中, 甚至代理对象都不知道有此调用的存在!

    知道问题的原因,解决方法就简单了,给自己定义个内部的引用,通过这个引用去调方法就能被AOP拦截到了。

    @Service
    public class SomeService {
        private Logger logger = LoggerFactory.getLogger(getClass());
    
        private SomeService self;
    
        public List<UserVo> getUserList(String someParam) {
            List<UserModel> userModelList= userDao.getUsers();
            return self.modelToVo(userModelList)
        }
    
        @MaskMethod
        public void modelToVo() {
    
        }
    }


    当然,更合理的是提取一个转换的servuce类,把这种转换方法提取到这个类里面,统一进行拦截。
    分享到:
    评论

    相关推荐

      Spring AOP完整例子

      在Spring AOP的例子中,我们可能会创建一个`@RunWith(SpringJUnit4ClassRunner.class)`标记的测试类,以利用Spring的测试支持。在测试方法中,可以注入需要的bean,然后调用方法来触发AOP代理。这样,通知将在适当的...

      反射实现 AOP 动态代理模式(Spring AOP 的实现原理)

      代理对象在调用方法时会触发InvocationHandler的invoke()方法,从而可以在这个方法中实现对方法调用的拦截。JDK动态代理要求被代理类必须实现一个接口,代理类会实现相同的接口。 Spring框架中的AOP模块使用了动态...

      spring aop依赖jar包

      现在,我们回到主题——"springaop依赖的jar包"。在Spring 2.5.6版本中,使用Spring AOP通常需要以下核心jar包: - `spring-aop.jar`:这是Spring AOP的核心库,包含了AOP相关的类和接口。 - `spring-beans.jar`:...

      springAOP中文文档

      假设我们有一个简单的服务类 `UserService`,我们需要在调用其方法时自动记录日志。 ##### 基于 AspectJ 的实现 首先定义一个切面类 `LoggingAspect`,并使用 `@Aspect` 注解标记: ```java @Aspect @Component ...

      Spring AOP面向方面编程原理:AOP概念

      在Spring AOP中,这个对象通常是业务逻辑实现类。 7. **AOP代理(AOP Proxy)**:由AOP框架创建的对象,用于包含通知逻辑。Spring提供了两种类型的代理:JDK动态代理和CGLIB代理。 8. **编织(Weaving)**:是指将...

      spring-boot aop

      本示例是关于如何在Spring Boot项目中实现AOP功能的一个简单演示。 首先,我们需要了解AOP的基本概念。AOP的核心是切面(Aspect),它封装了跨越多个对象的行为或关注点,如日志记录。切点(Pointcut)定义了在何处...

      SpringAOP的例子

      在这个"SpringAOP的例子"中,我们将深入探讨如何在Eclipse环境下利用Spring AOP和动态代理来实现这些功能。 首先,让我们理解什么是AOP。AOP是一种编程范式,旨在减少代码的重复性和增强可维护性。在传统的OOP中,...

      spring AOP入门实例

      在实际运行这个例子时,你可以看到Spring会自动创建切面的代理对象,当调用目标方法时,实际上是在调用代理对象,从而触发我们定义的通知。 通过这个简单的日志记录实例,我们可以看到Spring AOP如何优雅地处理横切...

      spring aop API示例

      例如,我们可以创建一个切面类,其中包含一个方法,该方法标记为`@Before`,并在该方法中添加需要在目标方法执行前运行的代码。 2. **After通知**: 不论方法是否正常结束,After通知总是在方法执行后触发。`@...

      spring aop练习

      Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来处理系统中的交叉关注点,比如日志、事务管理、性能监控等。在这个"spring aop练习"中,我们将深入探讨如何使用注解来...

      spring aop实例annotation方法实现

      在Spring中,可以使用`@Aspect`注解来定义一个切面类,然后在该类中定义通知方法。 ```java @Aspect public class LoggingAspect { @Before("execution(* com.example.service.*.*(..))") public void logBefore...

      spring之AOP(动态代理)

      `InvocationHandler`接口定义了一个`invoke`方法,当调用代理对象的方法时,这个方法会被触发,从而执行相应的通知。 接下来是CGLIB(Code Generation Library)动态代理。CGLIB是一个代码生成库,它可以在运行时为...

      springAop默认代理方式.zip

      然而,Spring AOP默认并不使用静态代理,因为它需要为每个被代理的对象创建一个具体的代理类,这在面对大量对象时会导致代码膨胀。 2. **动态代理**:Spring AOP 的默认代理方式是动态代理,它包括JDK动态代理和...

      spring aop 附带测试实例

      在提供的压缩包文件"springAOP"中,可能包含了以下内容: - **切面类(Aspect Class)**:包含切点和通知的Java类,可能使用了`@Aspect`注解。 - **目标类(Target Class)**:被AOP代理的对象,通常包含业务逻辑。...

      spring aop测试项目

      Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和解耦的编程方式,使得开发者可以将关注点分离到不同的切面中,而不是混杂在业务逻辑代码里。本测试项目旨在帮助理解并实践Spring AOP的...

      Spring AOP的底层实现技术

      比如,如果定义了一个前置通知,那么在调用目标方法之前,前置通知会被执行。 6. **CGLIB的原理** CGLIB是一个强大的高性能的代码生成库,它可以在运行期扩展Java类与实现Java接口。在Spring中,CGLIB通过继承目标...

      Java spring AOP源码

      Spring AOP通过构建一个拦截器链(interceptor chain)来实现方法的增强。每个拦截器都有机会在方法调用前后执行自己的逻辑。这种链式结构使得多个增强逻辑可以被灵活地组合在一起。 **5. **Spring AOP配置与使用**...

      SpringAOP测试Demo

      在"SpringAOP测试Demo"中,我们通常会涉及以下几个核心概念和操作: 1. **切面(Aspect)**:切面是关注点的一个模块化,它包括了连接点、通知、目标对象、织入和引入。在Spring AOP中,切面通常由一个或多个注解的...

      spring aop

      在Spring AOP中,切面可以由一个单独的类定义,这个类包含了通知和其他元数据。 - **通知(Advice)**:通知是在特定连接点上执行的代码,即切面的逻辑。Spring支持五种类型的通知:前置通知(Before)、后置通知...

      Spring AOP简单模拟

      3. **测试**:创建一个服务类`MyService`,然后在主程序中调用这个服务类的方法,观察日志输出。 ```java @Service public class MyService { public void doSomething() { // 方法逻辑 } } @SpringBoot...

    Global site tag (gtag.js) - Google Analytics