ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

源码解析为什么spring 被@Repository注解标识注入后是代理类

2021-07-06 15:52:01  阅读:144  来源: 互联网

标签:false Repository spring 代理 源码 result proxyFactory


背景

今天发现一个奇怪的问题,有一个类是用的@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
0 = {ApplicationContextAwareProcessor@4480}
1 = {WebApplicationContextServletContextAwareProcessor@4481}
2 = {ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor@4482}
3 = {PostProcessorRegistrationDelegate$BeanPostProcessorChecker@4483}
4 = {ConfigurationPropertiesBindingPostProcessor@4484}
5 = {MethodValidationPostProcessor@4391} "proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false"
6 = {PersistenceExceptionTranslationPostProcessor@4485} "proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false"
7 = {WebServerFactoryCustomizerBeanPostProcessor@4486}
8 = {ErrorPageRegistrarBeanPostProcessor@4487}
9 = {CommonAnnotationBeanPostProcessor@4488}
10 = {AutowiredAnnotationBeanPostProcessor@4489}
11 = {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修饰注入。

 

标签:false,Repository,spring,代理,源码,result,proxyFactory
来源: https://blog.51cto.com/u_14987832/2991435

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有