源码解析为什么spring 被@Repository注解标识注入后是代理类
2021/7/6 17:43:02
本文主要是介绍源码解析为什么spring 被@Repository注解标识注入后是代理类,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
背景
今天发现一个奇怪的问题,有一个类是用的@Repository注解标识注入的,并且这个类并没有配置任何带代理和aop配置。但是得到的这个类不是一个原生类,而是一个代理类,如果换成了Component注解这时候得到的类就是原生类 。下面分别演示下这两种情况。
先用@Repository注入得到的class是下面的:
class com.workit.demo.service.ServiceA$$EnhancerBySpringCGLIB$$4ee00fa9
然后@Component注入得到的class是下面的:
class com.workit.demo.service.ServiceA
下面我们就带着这个疑问为什么会出现这样的情况吧。我们可以根据spring ioc创建bean的源码调试最终确认是在哪里为其生成代理类的
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization这个方法如果看过spring ioc源码的人应该都比较熟悉。
@Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
getBeanPostProcessors() 总共有12个beanProcessors result = {CopyOnWriteArrayList@4450} size = 12 = {ApplicationContextAwareProcessor@4480} = {WebApplicationContextServletContextAwareProcessor@4481} = {ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor@4482} = {PostProcessorRegistrationDelegate$BeanPostProcessorChecker@4483} = {ConfigurationPropertiesBindingPostProcessor@4484} = {MethodValidationPostProcessor@4391} "proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false" = {PersistenceExceptionTranslationPostProcessor@4485} "proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false" = {WebServerFactoryCustomizerBeanPostProcessor@4486} = {ErrorPageRegistrarBeanPostProcessor@4487} = {CommonAnnotationBeanPostProcessor@4488} = {AutowiredAnnotationBeanPostProcessor@4489} = {ApplicationListenerDetector@4490}
经过断点调试我们最终发现为其生成代理类的是这个PersistenceExceptionTranslationPostProcessor。进入这个类的postProcessAfterInitialization方法,由于PersistenceExceptionTranslationPostProcessor继承了AbstractAdvisingBeanPostProcessor所以调用的是AbstractAdvisingBeanPostProcessor的postProcessAfterInitialization方法创建代理类的方法就是
if (this.isEligible(bean, beanName)) { ProxyFactory proxyFactory = this.prepareProxyFactory(bean, beanName); if (!proxyFactory.isProxyTargetClass()) { this.evaluateProxyInterfaces(bean.getClass(), proxyFactory); } proxyFactory.addAdvisor(this.advisor); this.customizeProxyFactory(proxyFactory); return proxyFactory.getProxy(this.getProxyClassLoader());
至于为什么如果有@Repository这个方法isEligible就会返回true的话,是因为isEligible方法里面会去判断当前类上面是否有注解Repository,如果有,spring则为其创建一个代理类。
总结
spring项目中如果引用了spring-tx的依赖,并且类上面被打上@Repository注解的类,spring都会被为其生存一个代理类。为何会生成一个代理类,主要的原因在PersistenceExceptionTranslationPostProcessor这个类,这个类是位于spring-tx下面的。如果我们希望得到一个原生类的话要么不引入spring-tx模块,或者不在类上面用Repository修饰注入。
这篇关于源码解析为什么spring 被@Repository注解标识注入后是代理类的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-22项目:远程温湿度检测系统
- 2024-12-21《鸿蒙HarmonyOS应用开发从入门到精通(第2版)》简介
- 2024-12-21后台管理系统开发教程:新手入门全指南
- 2024-12-21后台开发教程:新手入门及实战指南
- 2024-12-21后台综合解决方案教程:新手入门指南
- 2024-12-21接口模块封装教程:新手必备指南
- 2024-12-21请求动作封装教程:新手必看指南
- 2024-12-21RBAC的权限教程:从入门到实践
- 2024-12-21登录鉴权实战:新手入门教程
- 2024-12-21动态权限实战入门指南