场景
通过自定义注解记录用户访问日志,controller里面的接口使用了private修饰后获取不到service的bean导致的NullPointException。
原理
在Spring框架中,Controller层通常用于处理HTTP请求和返回响应。Controller中的方法可以是public
或private
,这两种访问修饰符在Spring中有不同的行为:
-
public方法:
public
方法可以被Spring容器管理,Spring可以自动检测到这些方法,并将其作为处理HTTP请求的入口。- 这些方法可以被Spring的AOP(面向切面编程)框架所拦截,也就是说,可以在这些方法执行前后添加额外的行为,比如日志记录、事务管理等。
-
private方法:
private
方法在Java中是类内部可见的,不能被类的外部访问。Spring AOP代理主要针对public
方法,因为它们是组件间的公共接口。- 当你将Controller中的方法设置为
private
,Spring AOP将无法对其进行代理,因为这些方法对于Spring容器来说不是可见的。因此,任何AOP的增强(advice)都不会应用到这些方法上。
至于为什么加入AOP后private
方法无法获取到Service的Bean,这主要是因为:
- AOP代理通常是基于方法的可见性来工作的。如果方法被标记为
private
,那么在Spring AOP的代理机制中,这些方法不会被认为是公共的API,因此不会被代理。 - 当AOP代理介入时,它会创建一个目标对象的代理,这个代理会拦截所有公共方法的调用。由于
private
方法不会被代理,因此它们不会经过AOP的拦截链,也就无法应用任何增强逻辑。 - 如果Service的Bean是通过AOP代理注入到Controller中的,那么
private
方法将无法看到或访问这个代理对象,因为它们没有被AOP机制所拦截。
总结
总结来说,如果你想要在Spring中使用AOP来增强Controller中的方法,你应该确保这些方法是public
的,这样Spring AOP才能够正确地应用增强逻辑。如果你需要在Controller内部使用Service的Bean,并且希望这些Service方法能够被AOP增强,那么你应该将Service中的方法也设置为public
。