关于Controller请求方法:private和public的区别

最近,在公司 codereview 会上,我给众多同事布置了“家庭作业”。controller 中的请求方法,通常我们都是 public 的,如果是 private 的、protected 的行不行,为什么?
后来一个同事比较认真,第二天早上测试后发现报错了,给我反馈说 private 方法的内部注入的 service 为 null,修改成 public 后就不会为 null。为什么会产生这个问题呢?这个同事没有回答出来,今天我抽空调试了一下源码,给大家总结一下,分享给大家!
首先简单模拟一下环境
public interface testservice {    string getteststring();}@service(testservice)public class testserviceimpl implements testservice {    @override    public string getteststring() {        return 业余草;    }}    @restcontrollerpublic class maincontroller {    @autowired    private testservice service;    @requestmapping(/testa)    public string testa(){        return service.getteststring();    }    @requestmapping(/testb)    private string testb(){        return service.getteststring();    }} /testa是 pulibc,/testb是 pirvate,测试结果「均能返回业余草字符串」
测试和公司环境还有一个不太同的就是公司项目中有 aop 切面处理访问日志的,还要添加一个 aop。
@aspect@componentpublic class weblogaspect {    private final logger logger = loggerfactory.getlogger(weblogaspect.class);    @pointcut(execution(public * com.spring.controller..*.*(..)))    public void controllerlog(){}    @before(controllerlog())    public void logbeforecontroller(joinpoint joinpoint) {        requestattributes requestattributes = requestcontextholder.getrequestattributes();        httpservletrequest request = ((servletrequestattributes)requestattributes).getrequest();        logger.info(*************url :  + request.getrequesturl().tostring());        logger.info(*************http_method :  + request.getmethod());        logger.info(*************ip :  + request.getremoteaddr());    }    } 添加了一个 aop 后测试:
/testa返回业余草字符串  /testb访问报错,service注入失败,为null 为什么使用 aop 会导致 private 修饰的方法注入失败,查询了许多资料,网上有人说到 org.springframework.aop.support.aoputils中的代码使用的是method[] methods = clazz.getmethods(),即是只能拿到 public 方法。但是我使用的版本2.1.4.release中已经使用method[] methods = reflectionutils.getalldeclaredmethods(clazz);这就有点迷惑了。
会不会是切点注解中的修饰符匹配不到呢?将切点中的修饰符从 public 修改成 private。
@pointcut(execution(private* com.spring.controller..*.*(..)))  public void controllerlog(){} 测试结果:
/testa返回业余草字符串  /testb访问报错,service注入失败,为null 还是不行(就挺秃然的)。
哎,想偷懒还不行,只能我一行一行调试代码了。
基于 spring boot + mybatis plus + vue & element 实现的后台管理系统 + 用户小程序,支持 rbac 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro
视频教程:https://doc.iocoder.cn/video/
目前结论
方法中没有用@autowired或者@resource注入的对象。有无 aop,任意修饰符都可以正常访问并且返回结果
方法中使用了@autowired或者@resource注入的对象没有 aop 切面的情况下,public,protected,private都能正常的映射在有 aop 切面的情况下,public,protected可以正常映射,但是使用private会报空指针异常,注入对象为 null。
最后经过我的一番折腾与调试之后,发现:
使用了 aop,也就是使用动态代理,你的 springboot 版本为 2.1.4 release,底层默认调用的是 cglib 作为动态代理。
其本质是:调用某个类的方法时,实际上是先为该类生成一个子类,然后再在子类中通过反射等,达到方法拦截的目的。对于子类,其父类中,private修饰的方法,子类如果与父类不在同一包下,是没有访问的权限的,此场景下,cglib 生成的子类,不会和父类在同一包下,也就是private修饰的方法,不能进行动态代理,所以会报空指针异常。


关于多功能、节能型的数据多功能电力仪表的介绍
国产单片机PY32F002B,32位ARM架构Cortex -M0+内核,性价比超高
新机iPhone8到底值不值得买?看完这三大槽点再决定购买iPhone8也不迟
电子线路的故障排除和调试的解决方案
海康存储新品牌的诞生与多款新品的首发
关于Controller请求方法:private和public的区别
DS28E25提供世界级的安全认证,以保护您的开发投资
可智能穿戴设备在移动医疗健康领域的应用
塑封贴片压敏电阻的优势有哪些?5大优势分享!
CES2012手机新品展望:Android4.0稀少 WP7或井喷
STM32F1_ 片内FLASH编程
2017年有望出台家用PM2.5测量仪校准规范
在MATLAB中调用Quartus SignalTap逻辑分析仪采集数据的方法
实现未来机器人的多样性!
EMC常见兼容问题及解决办法
新型导电油墨问世,无需掺杂就具备极佳导电性能
金立S11正式入网工信部:6GB+四个摄像头+全面屏组合
苏州华泰华芯太湖光子产业投资基金成立,聚焦光子芯片等领域
为任何系统增加USB
哪些大屏手机可以推荐?小米max,华为mate8给你不一样的视野范围!