1.2.0 增加 IRepository IQuery的工厂方法,避免无用的空白接口编写
This commit is contained in:
@@ -17,7 +17,7 @@ buildscript {
|
||||
|
||||
subprojects {
|
||||
group 'com.synebula'
|
||||
version '1.1.2'
|
||||
version '1.2.0'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
|
||||
@@ -2,16 +2,18 @@ package com.synebula.gaea.app.autoconfig.service
|
||||
|
||||
import com.synebula.gaea.data.serialization.IObjectMapper
|
||||
import com.synebula.gaea.domain.repository.IRepository
|
||||
import com.synebula.gaea.domain.repository.IRepositoryFactory
|
||||
import com.synebula.gaea.domain.service.Domain
|
||||
import com.synebula.gaea.domain.service.IService
|
||||
import com.synebula.gaea.domain.service.Service
|
||||
import com.synebula.gaea.domain.service.ServiceDependency
|
||||
import com.synebula.gaea.spring.autoconfig.Proxy
|
||||
import org.springframework.beans.factory.BeanFactory
|
||||
import java.io.InvalidClassException
|
||||
import java.lang.reflect.Method
|
||||
|
||||
class ServiceProxy(
|
||||
private var supertype: Class<*>, private var beanFactory: BeanFactory, implementBeanNames: Array<String> = arrayOf()
|
||||
private var supertype: Class<*>,
|
||||
private var beanFactory: BeanFactory, implementBeanNames: Array<String> = arrayOf()
|
||||
) : Proxy() {
|
||||
|
||||
private var service: IService<*>
|
||||
@@ -20,18 +22,26 @@ class ServiceProxy(
|
||||
// 如果没有实现类, 使用Service类代理
|
||||
if (implementBeanNames.isEmpty()) {
|
||||
// 如果没有实现类并且没有ServiceDependency注解, 则抛出异常
|
||||
if (!this.supertype.declaredAnnotations.any { it.annotationClass == ServiceDependency::class }) {
|
||||
if (!this.supertype.declaredAnnotations.any { it.annotationClass == Domain::class }) {
|
||||
throw InvalidClassException(
|
||||
"interface ${this.supertype.name} must has implementation class or annotation by ${ServiceDependency::class.qualifiedName}"
|
||||
"interface ${this.supertype.name} must has implementation class or annotation by ${Domain::class.qualifiedName}"
|
||||
)
|
||||
}
|
||||
val serviceDependency = this.supertype.getDeclaredAnnotation(ServiceDependency::class.java)
|
||||
val repo = this.beanFactory.getBean(serviceDependency.repo.java)
|
||||
val domain = this.supertype.getDeclaredAnnotation(Domain::class.java)
|
||||
|
||||
// repository工厂对象
|
||||
val defaultRepositoryFactory = this.beanFactory.getBean(IRepositoryFactory::class.java)
|
||||
val mapper = this.beanFactory.getBean(IObjectMapper::class.java)
|
||||
|
||||
val constructor = Service::class.java.getConstructor(
|
||||
Class::class.java, IRepository::class.java, IObjectMapper::class.java
|
||||
)
|
||||
this.service = constructor.newInstance(serviceDependency.clazz.java, repo, mapper)
|
||||
this.service =
|
||||
constructor.newInstance(
|
||||
domain.clazz.java,
|
||||
defaultRepositoryFactory.createRawRepository(domain.clazz.java),
|
||||
mapper
|
||||
)
|
||||
} else {
|
||||
this.service = this.beanFactory.getBean(implementBeanNames[0]) as IService<*>
|
||||
}
|
||||
|
||||
@@ -51,4 +51,16 @@ class MongodbRepoRegister : Register() {
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun addDefaultProxyBean(result: MutableMap<String, BeanDefinition>) {
|
||||
// IRepository proxy
|
||||
val builder = BeanDefinitionBuilder.genericBeanDefinition(IRepository::class.java)
|
||||
builder.addConstructorArgValue(IRepository::class.java)
|
||||
builder.addConstructorArgValue(this._beanFactory)
|
||||
builder.addConstructorArgValue(emptyArray<String>())
|
||||
val definition = builder.rawBeanDefinition as GenericBeanDefinition
|
||||
definition.beanClass = MongodbRepoFactory::class.java
|
||||
definition.autowireMode = GenericBeanDefinition.AUTOWIRE_BY_TYPE
|
||||
result[IRepository::class.java.name] = definition
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.synebula.gaea.mongodb.query
|
||||
|
||||
import com.synebula.gaea.query.IQuery
|
||||
import com.synebula.gaea.query.IQueryFactory
|
||||
import org.springframework.data.mongodb.core.MongoTemplate
|
||||
|
||||
class MongodbQueryFactory(var template: MongoTemplate) : IQueryFactory {
|
||||
|
||||
/**
|
||||
* 创建IQuery接口类型
|
||||
*/
|
||||
override fun createRawQuery(clazz: Class<*>): IQuery<*, *> {
|
||||
val constructor = MongodbQuery::class.java.getConstructor(Class::class.java, MongoTemplate::class.java)
|
||||
return constructor.newInstance(clazz, this.template)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建IQuery接口类型
|
||||
*/
|
||||
override fun <T, I> createQuery(clazz: Class<T>): IQuery<T, I> {
|
||||
return MongodbQuery(clazz, template)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.synebula.gaea.mongodb.repository
|
||||
|
||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
import com.synebula.gaea.domain.repository.IRepository
|
||||
import com.synebula.gaea.domain.repository.IRepositoryFactory
|
||||
import org.springframework.data.mongodb.core.MongoTemplate
|
||||
|
||||
class MongodbRepositoryFactory(var template: MongoTemplate) : IRepositoryFactory {
|
||||
|
||||
/**
|
||||
* 创建IRepository接口类型
|
||||
*/
|
||||
override fun createRawRepository(clazz: Class<*>): IRepository<*, *> {
|
||||
val constructor = MongodbRepository::class.java.getConstructor(Class::class.java, MongoTemplate::class.java)
|
||||
return constructor.newInstance(clazz, this.template)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建IRepository接口类型
|
||||
*/
|
||||
override fun <T : IAggregateRoot<I>, I> createRepository(clazz: Class<T>): IRepository<T, I> {
|
||||
return MongodbRepository(clazz, template)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.synebula.gaea.domain.repository
|
||||
|
||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
|
||||
/**
|
||||
* Repository 工厂接口。 定义了Repository的创建方法。
|
||||
*/
|
||||
interface IRepositoryFactory {
|
||||
|
||||
/**
|
||||
* 创建原始类型的IRepository接口类型
|
||||
*/
|
||||
fun createRawRepository(clazz: Class<*>): IRepository<*, *>
|
||||
|
||||
/**
|
||||
* 创建指定类型的IRepository接口类型
|
||||
*/
|
||||
fun <T : IAggregateRoot<I>, I> createRepository(clazz: Class<T>): IRepository<T, I>
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.synebula.gaea.domain.service
|
||||
|
||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* 声明服务依赖的聚合根,若服务没有实现类则可以根据依赖项自动组装服务。
|
||||
*
|
||||
* @param clazz 依赖的聚合根类型
|
||||
*/
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class Domain(val clazz: KClass<out IAggregateRoot<*>>)
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.synebula.gaea.domain.service
|
||||
|
||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||
import com.synebula.gaea.domain.repository.IRepository
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* 声明服务的依赖项,若服务没有实现类则可以根据依赖项自动组装服务。
|
||||
*
|
||||
* @param clazz 依赖的聚合根类型
|
||||
* @param repo 依赖的[IRepository]类型
|
||||
*/
|
||||
annotation class ServiceDependency(
|
||||
val clazz: KClass<out IAggregateRoot<*>>,
|
||||
val repo: KClass<out IRepository<*, *>>,
|
||||
)
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.synebula.gaea.query
|
||||
|
||||
|
||||
/**
|
||||
* Query 工厂接口。 定义了Query的创建方法。
|
||||
*/
|
||||
interface IQueryFactory {
|
||||
|
||||
/**
|
||||
* 创建原始类型的IQuery接口类型
|
||||
*/
|
||||
fun createRawQuery(clazz: Class<*>): IQuery<*, *>
|
||||
|
||||
/**
|
||||
* 创建指定类型的IQuery接口类型
|
||||
*/
|
||||
fun <T, I> createQuery(clazz: Class<T>): IQuery<T, I>
|
||||
}
|
||||
Reference in New Issue
Block a user