Jpa注入注解PersistenceContext和PersistenceUnit的处理器PersistenceAnnotationBeanPostProcessor实现原理

class PersistenceAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        // 找到jpa相关注解的元信息
        InjectionMetadata metadata = this.findPersistenceMetadata(beanName, beanType, (PropertyValues) null) {
            // 生成缓存Key
            String cacheKey = StringUtils.hasLength(beanName) ? beanName : clazz.getName();
            // 获取缓存
            InjectionMetadata metadata = (InjectionMetadata) this.injectionMetadataCache.get(cacheKey);
            // 如果需要刷新元数据
            // 因为第一次进入,metadata没有被缓存,所以都是为空的
            if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                // 加锁处理
                synchronized (this.injectionMetadataCache) {
                    // 再次校验有没有缓存过元数据
                    metadata = (InjectionMetadata) this.injectionMetadataCache.get(cacheKey);
                    if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                        // 如果存在元数据,清空,重新处理,因为可能并发处理了
                        if (metadata != null) {
                            // 清空之前处理的值
                            metadata.clear(pvs);
                        }
                        // 创建注入的元数据
                        metadata = this.buildPersistenceMetadata(clazz) {
                            // 确定当前类需要被注入,存在注入的注解PersistenceContext或者PersistenceUnit
                            if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(PersistenceContext.class, PersistenceUnit.class))) {
                                return InjectionMetadata.EMPTY;
                            }
                            // 保存所有需要注入的信息
                            List<InjectedElement> elements = new ArrayList();
                            Class targetClass = clazz;

                            do {
                                LinkedList<InjectedElement> currElements = new LinkedList();
                                // 找到当前注入类的所有字段,字段注入
                                ReflectionUtils.doWithLocalFields(targetClass, (field) -> {
                                    if (field.isAnnotationPresent(PersistenceContext.class) || field.isAnnotationPresent(PersistenceUnit.class)) {
                                        // 不支持注入静态的字段
                                        if (Modifier.isStatic(field.getModifiers())) {
                                            throw new IllegalStateException("Persistence annotations are not supported on static fields");
                                        }
                                        // 将字段封装成PersistenceElement对象,保存字段信息
                                        currElements.add(new PersistenceAnnotationBeanPostProcessor.PersistenceElement(field, field, (PropertyDescriptor) null));
                                    }

                                });
                                // 找到所有的方法,方法注入
                                // 和字段注入基本一样
                                ReflectionUtils.doWithLocalMethods(targetClass, (method) -> {
                                    Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
                                    if (BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                                        if ((bridgedMethod.isAnnotationPresent(PersistenceContext.class) || bridgedMethod.isAnnotationPresent(PersistenceUnit.class)) && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                                            // 静态的方法抛出异常
                                            if (Modifier.isStatic(method.getModifiers())) {
                                                throw new IllegalStateException("Persistence annotations are not supported on static methods");
                                            }
                                            // 如果注入的参数不是一个,也抛出异常
                                            if (method.getParameterCount() != 1) {
                                                throw new IllegalStateException("Persistence annotation requires a single-arg method: " + method);
                                            }
                                            // PropertyDescriptor是对JavaBean属性的抽象访问
                                            PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                                            // 将方法封装成PersistenceElement对象,保存方法信息和以及对方法的抽象访问
                                            currElements.add(new PersistenceAnnotationBeanPostProcessor.PersistenceElement(method, bridgedMethod, pd) {
                                                PersistenceContext pc = (PersistenceContext) ae.getAnnotation(PersistenceContext.class);
                                                PersistenceUnit pu = (PersistenceUnit) ae.getAnnotation(PersistenceUnit.class);
                                                // 注入注入的资源类型为EntityManager
                                                Class<?> resourceType = EntityManager.class;
                                                // 如果存在PersistenceContext注解信息
                                                if(pc !=null)

                                                {
                                                    // 并且同时存在PersistenceUnit
                                                    // 抛出异常
                                                    if (pu != null) {
                                                        throw new IllegalStateException("Member may only be annotated with either @PersistenceContext or @PersistenceUnit, not both: " + member);
                                                    }

                                                    Properties properties = null;
                                                    // 获取PersistenceContext注解的properties属性
                                                    // 它是一个注解PersistenceProperty的数组
                                                    PersistenceProperty[] pps = pc.properties();
                                                    // 如果设置了properties的属性值
                                                    if (!ObjectUtils.isEmpty(pps)) {
                                                        // 将PersistenceContext中的属性封装成Properties对象
                                                        properties = new Properties();
                                                        for (PersistenceProperty pp : pps) {
                                                            properties.setProperty(pp.name(), pp.value());
                                                        }
                                                    }
                                                    // JNDI单元资源名称
                                                    this.unitName = pc.unitName();
                                                    // 指定是使用事务范围的持久化上下文还是扩展持久化上下文
                                                    this.type = pc.type();
                                                    // 指定持久化上下文是否总是自动与当前事务同步,或者持久化上下文是否必须通过EntityManager方法显式地连接到当前事务
                                                    this.synchronizedWithTransaction = SynchronizationType.SYNCHRONIZED.equals(pc.synchronization());
                                                    // 设置的属性值
                                                    this.properties = properties;
                                                } else

                                                {
                                                    // 如果不存在PersistenceContext注解信息
                                                    // 那么资源类型变为EntityManagerFactory的工厂类型
                                                    resourceType = PersistenceContext.class;
                                                    // JNDI单元资源名称
                                                    this.unitName = pu.unitName();
                                                }
                                                // 校验资源类型,注入的字段类型必须与注解对应的类型是一致的,否则抛出异常
                                                // 存在PersistenceContext注解: 那么注入的是EntityManager类型
                                                // 如果不存在PersistenceContext注解: 使用PersistenceContext类型
                                                this.

                                                checkResourceType(resourceType)
                                            });
                                        }

                                    }
                                });
                                // 保存所有的字段注入和方法注入信息
                                elements.addAll(0, currElements);
                                // 继续扫描父类
                                targetClass = targetClass.getSuperclass();
                            } while (targetClass != null && targetClass != Object.class);
                            // 将当前类中字段注入和方法注入的信息封装成InjectionMetadata注入元信息
                            return InjectionMetadata.forElements(elements, clazz);
                        }
                        // 缓存字段注入的元信息
                        this.injectionMetadataCache.put(cacheKey, metadata);
                    }
                }
            }

            return metadata;
        }
        // 空实现
        metadata.checkConfigMembers(beanDefinition) {
            Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
            // 遍历所有注入的元素信息
            for (InjectedElement element : this.injectedElements) {
                // 获取成员信息,Member是Method,Field的抽象
                Member member = element.getMember();
                // 判断member是不是由Spring管理和调用,默认返回false,表示不是Spring管理的
                // 那么就需要交给Spring进行管理
                if (!beanDefinition.isExternallyManagedConfigMember(member)) {
                    // 将成员交给Spring管理和调用
                    beanDefinition.registerExternallyManagedConfigMember(member);
                    // 保存被校验了的元素
                    checkedElements.add(element);
                }
            }
            // 这个保存的是所有没有被外部管理的配置成员的元素信息
            // 如果被外部成员管理,beanDefinition.isExternallyManagedConfigMember(member)就为true,表示已经被管理了
            // 就不需要再次管理,只需要管理一次
            this.checkedElements = checkedElements;
        }
    }

    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        // 获取注入的元信息,在postProcessMergedBeanDefinition方法中就以及处理过,并缓存了
        InjectionMetadata metadata = findPersistenceMetadata(beanName, bean.getClass(), pvs);
        // 依赖注入
        metadata.inject(bean, beanName, pvs);
        {
            // 具体了可以看postProcessMergedBeanDefinition方法,因为都是在postProcessMergedBeanDefinition提前完成了操作
            Collection<InjectedElement> checkedElements = this.checkedElements;
            Collection<InjectedElement> elementsToIterate = (checkedElements != null ? checkedElements : this.injectedElements);
            // 如果存在需要注入的信息
            if (!elementsToIterate.isEmpty()) {
                // 遍历所有的元素
                for (InjectedElement element : elementsToIterate) {
                    // 注入
                    element.inject(target, beanName, pvs) {
                        // 如果是字段
                        if (this.isField) {
                            Field field = (Field) this.member;
                            ReflectionUtils.makeAccessible(field);
                            // 反射设置
                            field.set(target, getResourceToInject(target, requestingBeanName) {
                                // 根据这个类型来决定是解析EntityManager还是EntityManagerFactory
                                if (this.type != null) {
                                    // 如果注解配置的类型为EXTENDED
                                    return (this.type == PersistenceContextType.EXTENDED ?
                                            // 解析扩展的EntityManager
                                            resolveExtendedEntityManager(target, requestingBeanName) {
                                        // 先查找JNDI配置的EntityManager对象
                                        EntityManager em = getPersistenceContext(this.unitName, true)
                                        // 如果没有配置JNDI
                                        if (em == null) {
                                            // 查找JNDI配置的EntityManagerFactory
                                            EntityManagerFactory emf = getPersistenceUnit(this.unitName);
                                            // 没有配置JNDI
                                            if (emf == null) {
                                                // 从Spring中获取EntityManagerFactory
                                                emf = findEntityManagerFactory(this.unitName, requestingBeanName);
                                            }
                                            // 使用EntityManagerFactory创建EntityManager对象,根据注解配置的属性信息
                                            // 返回的是一个JDK代理对象
                                            em = ExtendedEntityManagerCreator.createContainerManagedEntityManager(emf, this.properties, this.synchronizedWithTransaction);
                                        }
                                        if (em instanceof EntityManagerProxy && beanFactory != null && requestingBeanName != null &&
                                                beanFactory.containsBean(requestingBeanName) && !beanFactory.isPrototype(requestingBeanName)) {
                                            // 保存需要扩展的EntityManager,Bean销毁的时候需要关闭
                                            extendedEntityManagersToClose.put(target, ((EntityManagerProxy) em).getTargetEntityManager());
                                        }
                                        return em;
                                    } :
                                    // 如果类型为TRANSACTION(默认),解析普通的EntityManager
                                    resolveEntityManager(requestingBeanName)){
                                        // 先查找JNDI配置的EntityManager对象
                                        EntityManager em = getPersistenceContext(this.unitName, false);
                                        // 如果没有配置JNDI
                                        if (em == null) {
                                            // 查找JNDI配置的EntityManagerFactory
                                            EntityManagerFactory emf = getPersistenceUnit(this.unitName);
                                            if (emf == null) {
                                                // 从Spring中获取EntityManagerFactory
                                                emf = findEntityManagerFactory(this.unitName, requestingBeanName);
                                            }
                                            // 使用EntityManagerFactory创建EntityManager对象,根据注解配置的属性信息
                                            // 返回的是一个JDK代理对象
                                            em = SharedEntityManagerCreator.createSharedEntityManager(emf, this.properties, this.synchronizedWithTransaction, getResourceType());
                                        }
                                        return em;
                                    }
                                } else {
                                    // 如果type为空,表示注解是@PersistenceUnit,它只需要注入EntityManagerFactory就ok
                                    return resolveEntityManagerFactory(requestingBeanName) {
                                        // 查找JNDI配置的EntityManagerFactory
                                        EntityManagerFactory emf = getPersistenceUnit(this.unitName);
                                        if (emf == null) {
                                            // 从Spring中获取EntityManagerFactory
                                            emf = findEntityManagerFactory(this.unitName, requestingBeanName);
                                        }
                                        return emf;
                                    }
                                }
                            });
                        } else {
                            // 方法注入
                            if (checkPropertySkipping(pvs)) {
                                return;
                            }
                            // 和上面字段注入一样
                            Method method = (Method) this.member;
                            ReflectionUtils.makeAccessible(method);
                            method.invoke(target, getResourceToInject(target, requestingBeanName));
                        }
                    }
                }
            }
        }
        return pvs;
    }
}

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值