zoukankan      html  css  js  c++  java
  • 从EnableJpaRepositories说开去

    1 、spring boot

    @EnableJpaRepositories(
            repositoryBaseClass = BaseRepositoryImpl.class,
            includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = BaseRepository.class),
            excludeFilters = @ComponentScan.Filter(NoRepositoryBean.class),
            repositoryFactoryBeanClass = BaseRepositoryFactoryBean.class
    )

    从EnableJpaRepositories的源代码里面可以看到相关的默认值

     1 @EnableJpaRepositories(
     2     basePackages = {},
     3     basePackageClasses = {},
     4     includeFilters = {},
     5     excludeFilters = {},
     6     repositoryImplementationPostfix = "Impl",
     7     namedQueriesLocation = "",//META-INF/jpa-named-queries.properties
     8     queryLookupStrategy=QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND, //QueryLookupStrategy.Key.x
     9     repositoryFactoryBeanClass=JpaRepositoryFactoryBean.class, //class
    10     entityManagerFactoryRef="entityManagerFactory",
    11     transactionManagerRef="transactionManager",
    12     considerNestedRepositories=false, 
    13     enableDefaultTransactions=true
    14 )

    2、 FilterType 说明

    public enum FilterType {
    
        /**
         * Filter candidates marked with a given annotation.
         * @see org.springframework.core.type.filter.AnnotationTypeFilter
         */
        ANNOTATION,
    
        /**
         * Filter candidates assignable to a given type.
         * @see org.springframework.core.type.filter.AssignableTypeFilter
         */
        ASSIGNABLE_TYPE,
    
        /**
         * Filter candidates matching a given AspectJ type pattern expression.
         * @see org.springframework.core.type.filter.AspectJTypeFilter
         */
        ASPECTJ,
    
        /**
         * Filter candidates matching a given regex pattern.
         * @see org.springframework.core.type.filter.RegexPatternTypeFilter
         */
        REGEX,
    
        /** Filter candidates using a given custom
         * {@link org.springframework.core.type.filter.TypeFilter} implementation.
         */
        CUSTOM
    
    }

    3、  JpaRepositoryFactoryBean

    FactoryBean 是一个可以在 IOC而容器中被管理的一个 bean,  是对各种处理过程和资源使用的抽象,  FactoryBean 在需要

    时产生另一个对象,而不返回 FactoryBean本身,   我们可以把它看成是一个抽象工厂,对它的调用返回的是工厂生产的产

    品,  如对代理对象的处理,对事务性代理的处理等

    public class JpaRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends
            TransactionalRepositoryFactoryBeanSupport<T, S, ID> {
    
        private EntityManager entityManager;
    
        /**
         * The {@link EntityManager} to be used.
         * 
         * @param entityManager the entityManager to set
         */
        @PersistenceContext
        public void setEntityManager(EntityManager entityManager) {
            this.entityManager = entityManager;
        }
    
    
        @Override
        public void setMappingContext(MappingContext<?, ?> mappingContext) {
            super.setMappingContext(mappingContext);
        }
    
    /*
       * 看这里
       */
    @Override
    protected RepositoryFactorySupport doCreateRepositoryFactory() { return createRepositoryFactory(entityManager); } protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) { return new JpaRepositoryFactory(entityManager); } @Override public void afterPropertiesSet() { Assert.notNull(entityManager, "EntityManager must not be null!"); super.afterPropertiesSet(); } }

    4、  JpaRepositoryFactory

        /*
         * Create a repository instance as backing for the query proxy.
       * 实例化自定义RepositoryImpl时,会注入EntityManager    
    */ @Override protected Object getTargetRepository(RepositoryInformation information) { SimpleJpaRepository<?, ?> repository = getTargetRepository(information, entityManager); repository.setRepositoryMethodMetadata(crudMethodMetadataPostProcessor.getCrudMethodMetadata()); return repository; } /** * Callback to create a {@link JpaRepository} instance with the given {@link EntityManager}
       *
    */ protected <T, ID extends Serializable> SimpleJpaRepository<?, ?> getTargetRepository(RepositoryInformation information, EntityManager entityManager) { JpaEntityInformation<?, Serializable> entityInformation = getEntityInformation(information.getDomainType()); return getTargetRepositoryViaReflection(information, entityInformation, entityManager); } /** * Returns the base class backing the actual repository instance. Make sure * {@link #getTargetRepository(RepositoryMetadata)} returns an instance of this class. */ @Override protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) { if (isQueryDslExecutor(metadata.getRepositoryInterface())) { return QueryDslJpaRepository.class; } else { return SimpleJpaRepository.class; } }

    5、 自定义的RepositoryImpl时,注入自身项目的SessionContext(或者是其他依赖), 如何处理

    其实Repository不应该注入SessionContext

    解答:

    重写JpaRepositoryFactory 的 getTargetRepository(RepositoryInformation information)方法

    public class BaseRepositoryFactoryBean<R extends JpaRepository<T, ID>, T, ID extends Serializable> extends JpaRepositoryFactoryBean<R, T, ID> {
    
        @Autowired
        private ISessionContext sessionContext;
    
        @Override
        protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
    
            return new BaseRepositoryFactory(entityManager);
        }
    
        private class BaseRepositoryFactory<T extends BaseEntity, I extends Serializable>
                extends JpaRepositoryFactory {
    
            private final EntityManager entityManager;
    
            public BaseRepositoryFactory(EntityManager entityManager) {
                super(entityManager);
                this.entityManager = entityManager;
            }
    
            @Override
            protected Object getTargetRepository(RepositoryInformation information) {
                Class<T> clazz = (Class<T>) information.getDomainType();
                JpaEntityInformation<T, ID> entityInformation = getEntityInformation(clazz);
                return new BaseRepositoryImpl<>(entityInformation, entityManager, sessionContext);
            }
    
            @Override
            protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
                return BaseRepositoryImpl.class;
            }
        }
    
    }
  • 相关阅读:
    How to configure security of ActiveMQ ?
    CentOS 搭建 nginx + tomcat
    25个 Git 进阶技巧
    写给Git初学者的7个建议
    my links
    Shell scripts to Create a local dir base on the time.
    81For全栈技术网
    一款可视化的在线制作H5
    在线制作h5
    在线制作h5——上帝的礼物
  • 原文地址:https://www.cnblogs.com/yuyutianxia/p/8185033.html
Copyright © 2011-2022 走看看