文档章节

spring aop 代理private方法 报错的问题分析

my_juke
 my_juke
发布于 06/27 13:59
字数 487
阅读 19
收藏 0

spring aop 代理private方法报空指针的问题

这两天做aop切面日志时,发现private方法报空指针。
原切入点配置如下:

    @Pointcut("@within(org.springframework.web.bind.annotation.RestController)")
    public void logPoint(){

    };

当某个Controller类中含有private方法,并且该类有需要spring注入的对象时,且在该私有方法有中使用spring注入的对象时会报空指针。
那么为什么会报空指针了。咱们看一下动态代理的过程,这里使用的是cglib代理。

  Enhancer enhancer = new Enhancer();
        enhancer.setCallback(new MyInteceptor());
        enhancer.setSuperclass(A1.class);
        A1 proxy = (A1)enhancer.create();

上面是一个创建cglib代理的类。
这里有一点要记住,private和final修饰的方法,不会被代理。也就是说private和final的方法不会进入callBack。如果进入不了callBack,那么就进入不了被代理的目标对象。那么只能在proxy对象上执行private或final修饰的方法。而proxy对象是由cglib实例化的,里面没有spring注入的对象。因些报空指针。

看个示例:
这是一个A1类,里面有一个say1的私有方法。

public class A1 {

    public void say(){
        System.out.println("say");
        say1();;
    }

    private void say1(){
        System.out.println("say1");
    }

    private void say2(){
        System.out.println("say2");
    }

    void say3(){
        System.out.println("say3");
    }
}

这里A类,包含callBack

public class A {

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\code");
        Enhancer enhancer = new Enhancer();
        enhancer.setCallback(new MyInteceptor());
        enhancer.setSuperclass(A1.class);
        A1 proxy = (A1)enhancer.create();
        System.out.println(proxy.getClass());
        Method[] ms = proxy.getClass().getMethods();
        proxy.say();;
        Method method = A1.class.getDeclaredMethod("say2",null);
        method.setAccessible(true);
        method.invoke(proxy,null);
        System.out.println("ok");
    }

    static class MyInteceptor implements MethodInterceptor {

        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println("before:"+method.getName());
            Object obj = methodProxy.invokeSuper(o,objects);

            System.out.println("after:"+method.getName());
            return null;
        }
    }
}

运行后say2没有被代理,也就是说没有进入callBack。 相同的方式通过反射获取say方法,可以进入callBack。

© 著作权归作者所有

my_juke
粉丝 4
博文 34
码字总数 22261
作品 0
深圳
私信 提问
哪些方法不能够实施Spring AOP事务

哪些方法不能够实施Spring AOP事务 由于Spring事务管理是基于接口代理或动态字节码技术。通过AOP实施事务增强。 基于接口动态代理的AOP事务增强,接口方法必须都是public的。 实现类的方法也...

hyssop
2014/12/06
0
0
深入解析Spring架构与设计原理-AOP

关于AOP的个人理解 AOP联盟定义的AOP体系结构把与AOP相关的概念大致分为了由高到低、从使用到实现的三个层次。关于这个体系结构,个人的理解是这样的,从上往下,最高层是语言和开发环境,在...

Java小铺
2018/08/27
0
0
Spring AOP 切面编程记录日志和接口执行时间

最近客户现在提出系统访问非常慢,需要优化提升访问速度,在排查了nginx、tomcat内存和服务器负载之后,判断是数据库查询速度慢,进一步排查发现是因为部分视图和表查询特别慢导致了整个系统...

编程SHA
2018/12/17
0
0
AOP切入elasticsearch 的 Java API RestHighLevelClient的search失败的其他解决方案?

最近打算在现有的系统基础上,基于用户的权限做数据的过滤。但是考虑的现有系统已经有一定的规模,所以决定在数据源客户端层面用aop 在查询前切入,修改查询的条件,达到数据权限过滤的效果,...

MyOldTime
05/23
0
0
一个常见的Spring IOC疑难症状

Case 请看下面的IOC实例: 1)AaaService实现AaaaInterface接口 2)在BaaService中Autowired AaaService Code Java代码 //1.AaaInterface package com.test; public interface AaaInterface......

stamen
2015/08/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

链接命令ln

命令ln 用途:在文件之间建立连接(link) 语法: ]# ln [选项] 源 [目标] 选项: -s, --symbolic 建立符号连接(以路径的形式存在,类似Windows系统的快捷方式), ...

迷失De挣扎
31分钟前
2
0
小白讲网络安全系列

注入攻击防护 XSS注入 SQL注入 命令注入 文件上传 文件解压缩 CSRF防护 对称加密 非对称加密 数字证书 数字签名 完整性校验 消息验证码 单向散列Hash函数 口令单向加密算法 审计日志 认证鉴权...

一刀
今天
2
0
MYSQL 嵌套事务(SAVEPOINT) 与Spring 事务传播

摘要 savepoint 关键字可以实现嵌套事务。结合savepoint关键字,更方便理解spring的事务传播。 事务嵌套 初始化表脚本 drop table t;create table t(a int, primary key(a)); 开启事务 my...

liangxiao
今天
4
0
Chrome OS 更新新版本可让Linux访问USB连接的Android设备

谷歌再次为Chrome OS带来了重大版本更新,使版本号达到了75。本次更新的一大亮点就是允许在Chrome OS上运行的Linux能够识别通过USB方式连接的Android设备,能够让用户使用Linux进行调试等等。...

linuxCool
昨天
15
0
聊聊feign的HystrixInvocationHandler

序 本文主要研究一下feign的HystrixInvocationHandler HystrixInvocationHandler feign-hystrix-10.2.3-sources.jar!/feign/hystrix/HystrixInvocationHandler.java final class HystrixInvo......

go4it
昨天
17
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部