Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jdbc</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<version>1.0.0.DATAJDBC-100-SNAPSHOT</version>

<name>Spring Data JDBC</name>
<description>Spring Data module for JDBC repositories.</description>
Expand Down Expand Up @@ -234,4 +234,4 @@
</pluginRepository>
</pluginRepositories>

</project>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.jdbc.repository.config;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Import;
import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactoryBean;

/**
* Annotation to enable JDBC repositories. Will scan the package of the annotated configuration class for Spring Data
* repositories by default.
*
* @author Jens Schauder
* @since 2.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(JdbcRepositoriesRegistrar.class)
public @interface EnableJdbcRepositories {

/**
* Alias for the {@link #basePackages()} attribute. Allows for more concise annotation declarations e.g.:
* {@code @EnableJpaRepositories("org.my.pkg")} instead of {@code @EnableJpaRepositories(basePackages="org.my.pkg")}.
*/
String[] value() default {};

/**
* Base packages to scan for annotated components. {@link #value()} is an alias for (and mutually exclusive with) this
* attribute. Use {@link #basePackageClasses()} for a type-safe alternative to String-based package names.
*/
String[] basePackages() default {};

/**
* Type-safe alternative to {@link #basePackages()} for specifying the packages to scan for annotated components. The
* package of each class specified will be scanned. Consider creating a special no-op marker class or interface in
* each package that serves no purpose other than being referenced by this attribute.
*/
Class<?>[] basePackageClasses() default {};

/**
* Specifies which types are eligible for component scanning. Further narrows the set of candidate components from
* everything in {@link #basePackages()} to everything in the base packages that matches the given filter or filters.
*/
Filter[] includeFilters() default {};

/**
* Specifies which types are not eligible for component scanning.
*/
Filter[] excludeFilters() default {};

/**
* Configures whether nested repository-interfaces (e.g. defined as inner classes) should be discovered by the
* repositories infrastructure.
*/
boolean considerNestedRepositories() default false;

/**
* Returns the {@link FactoryBean} class to be used for each repository instance. Defaults to
* {@link JdbcRepositoryFactoryBean}.
*/
Class<?> repositoryFactoryBeanClass() default JdbcRepositoryFactoryBean.class;

/**
* Configures the location of where to find the Spring Data named queries properties file. Will default to
* {@code META-INF/jdbc-named-queries.properties}.
*/
String namedQueriesLocation() default "";

/**
* Returns the postfix to be used when looking up custom repository implementations. Defaults to {@literal Impl}. So
* for a repository named {@code PersonRepository} the corresponding implementation class will be looked up scanning
* for {@code PersonRepositoryImpl}.
*/
String repositoryImplementationPostfix() default "Impl";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.jdbc.repository.config;

import java.lang.annotation.Annotation;

import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport;
import org.springframework.data.repository.config.RepositoryConfigurationExtension;

/**
* {@link ImportBeanDefinitionRegistrar} to enable {@link EnableJdbcRepositories} annotation.
*
* @author Jens Schauder
* @since 2.0
*/
class JdbcRepositoriesRegistrar extends RepositoryBeanDefinitionRegistrarSupport {

/*
* (non-Javadoc)
* @see org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport#getAnnotation()
*/
@Override
protected Class<? extends Annotation> getAnnotation() {
return EnableJdbcRepositories.class;
}

/*
* (non-Javadoc)
* @see org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport#getExtension()
*/
@Override
protected RepositoryConfigurationExtension getExtension() {
return new JdbcRepositoryConfigExtension();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.jdbc.repository.config;

import java.util.Locale;

import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactoryBean;
import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;

/**
* {@link org.springframework.data.repository.config.RepositoryConfigurationExtension} extending the repository
* registration process by registering JDBC repositories.
*
* @author Jens Schauder
* @since 2.0
*/
public class JdbcRepositoryConfigExtension extends RepositoryConfigurationExtensionSupport {

/*
* (non-Javadoc
* @see org.springframework.data.repository.config.RepositoryConfigurationExtension#getModuleName()
*/
@Override
public String getModuleName() {
return "JDBC";
}

/*
* (non-Javadoc
* @see * @see org.springframework.data.repository.config
.RepositoryConfigurationExtensionSupport#getRepositoryFactoryBeanClassName()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weird line break.

*/
@Override
public String getRepositoryFactoryBeanClassName() {
return JdbcRepositoryFactoryBean.class.getName();
}

/*
* (non-Javadoc
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getModulePrefix()
*/
@Override
protected String getModulePrefix() {
return getModuleName().toLowerCase(Locale.US);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.jdbc.repository.support;

import java.io.Serializable;
import java.util.Map;
import java.util.Optional;

import javax.sql.DataSource;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import org.springframework.data.repository.core.support.TransactionalRepositoryFactoryBeanSupport;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

/**
* Special adapter for Springs {@link org.springframework.beans.factory.FactoryBean} interface to allow easy setup of
* repository factories via Spring configuration.
*
* @author Jens Schauder
* @since 2.0
*/
public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> //
extends TransactionalRepositoryFactoryBeanSupport<T, S, ID> {

private static final String NO_NAMED_PARAMETER_JDBC_OPERATION_ERROR_MESSAGE = //
"No unique NamedParameterJdbcOperation could be found, " //
+ "nor JdbcOperations or DataSource to construct one from.";

private final ApplicationEventPublisher applicationEventPublisher;
private final ApplicationContext context;

JdbcRepositoryFactoryBean(Class<? extends T> repositoryInterface, ApplicationEventPublisher applicationEventPublisher,
ApplicationContext context) {

super(repositoryInterface);
this.applicationEventPublisher = applicationEventPublisher;
this.context = context;
}

@Override
protected RepositoryFactorySupport doCreateRepositoryFactory() {
return new JdbcRepositoryFactory(findOrCreateJdbcOperations(), applicationEventPublisher);
}

private NamedParameterJdbcOperations findOrCreateJdbcOperations() {

return getNamedParameterJdbcOperations() //
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove nesting by using Optionals.firstNonEmpty(…)-

.orElseGet(() -> getJdbcOperations().map(NamedParameterJdbcTemplate::new) //
.orElseGet(() -> getDataSource().map(NamedParameterJdbcTemplate::new) //
.orElseThrow(() -> new IllegalStateException( //
NO_NAMED_PARAMETER_JDBC_OPERATION_ERROR_MESSAGE //
))));
}

private Optional<NamedParameterJdbcOperations> getNamedParameterJdbcOperations() {
return getBean(NamedParameterJdbcOperations.class, "namedParameterJdbcOperations");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Names as constants. Align with Boot defaults, i.e. Operations -> Template. Types should stay with Operations.

}

private Optional<JdbcOperations> getJdbcOperations() {
return getBean(JdbcOperations.class, "jdbcOperations");
}

private Optional<DataSource> getDataSource() {
return getBean(DataSource.class, "dataSource");
}

private <R> Optional<R> getBean(Class<R> type, String name) {

Map<String, R> beansOfType = context.getBeansOfType(type);

if (beansOfType.size() == 1) {
return beansOfType.values().stream().findFirst();
}

return Optional.ofNullable(beansOfType.get(name));
}
}
Loading