解决:is not eligible for getting processed by all BeanPostProcessors

得意时要看淡,失意时要看开。不论得意失意,切莫大意;不论成功失败,切莫止步。志得意满时,需要的是淡然,给自己留一条退路;失意落魄时,需要的是泰然,给自己觅一条出路解决:is not eligible for getting processed by all BeanPostProcessors,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

问题描述

SpringBoot项目整合Shiro框架后启动,启动日志里大概会看到下面的日志:

...
(org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:376) - Bean 'userServiceImpl' of type [com.xxx.impl.UserServiceImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
...
(org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:376) - Bean 'jwtRealm' of type [com.xxx.JWTRealm] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
(org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:376) - Bean 'securityManager' of type [org.apache.shiro.web.mgt.DefaultWebSecurityManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
(org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:376) - Bean 'authorizationAttributeSourceAdvisor' of type [org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)、

中文描述:
xxx这个bean不能被所有的BeanPostProcessors处理(比如:自动代理(即:AOP))

这几个bean(称为业务bean)不会被所有BeanPostProcessor(BPP)处理。BPP是spring的内置的基础bean,用于在实例化业务bean前后处理一些逻辑,可以更改业务bean的行为甚至返回另一个bean(大名鼎鼎的AOP就是通过BPP实现)。

依赖了UserService的某个bean实现了BeanPostProcessor之类的接口,导致userServiceImpl被提前注入,导致无法被AOP。

分析

在项目中的ShiroConfig文件中使用了ShiroFilterFactoryBean,它也实现了BeanPostProcessor接口。

上面的错误信息,查看Spring源码,是在BeanPostProcessorChecker中定义的:

	/**
	 * BeanPostProcessor that logs an info message when a bean is created during
	 * BeanPostProcessor instantiation, i.e. when a bean is not eligible for
	 * getting processed by all BeanPostProcessors.
	 */
	private static final class BeanPostProcessorChecker implements BeanPostProcessor {
		...
	}

总结

出问题的原因:业务bean在BPP实例化前被实例化了。理想情况下应该让spring先实例化所有的BPP后,再实例化我们的业务bean,这样业务bean才能被所有BPP处理,如果有业务bean先于任何BPP实例化,那么这个业务bean就不会被还未实例化的BPP处理了,这个就是日志提示的原因。

解决

方案1:延迟初始化

可以使用延迟初始化来解决。延迟初始化会在IOC的时候先给出一个代理类,IOC之后的AOP这个BeanPostProcessor会正常地给它处理。

具体做法
加一个注解即可:@Lazy。可以在两个地方加这个注解:字段、方法参数。
方法1:加到字段上
方法2:加到构造方法的参数上

方案2:@Role(BeanDefinition.ROLE_INFRASTRUCTURE)

方案说明
在Bean的声明上加个注解:@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
表明这个bean是完全后台模式,不需要被代理。

原理,就是BeanPostProcessorChecker的下面这个方法:

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
	if (!(bean instanceof BeanPostProcessor) && !isInfrastructureBean(beanName) &&
			this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) {
		if (logger.isInfoEnabled()) {
			logger.info("Bean '" + beanName + "' of type [" + bean.getClass().getName() +
					"] is not eligible for getting processed by all BeanPostProcessors " +
					"(for example: not eligible for auto-proxying)");
		}
	}
	return bean;
}

参考

https://www.jianshu.com/p/b1209cd3686d

https://www.baeldung.com/spring-not-eligible-for-auto-proxying

https://stackoverflow.com/questions/1201726/tracking-down-cause-of-springs-not-eligible-for-auto-proxying

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/155625.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!