从EnableJpaRepositories说开去

泪湿孤枕 提交于 2020-02-02 20:01:09

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;
        }
    }

}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!