1.2.0 增加 IRepository IQuery的工厂方法,避免无用的空白接口编写
This commit is contained in:
@@ -17,7 +17,7 @@ buildscript {
|
|||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
group 'com.synebula'
|
group 'com.synebula'
|
||||||
version '1.1.2'
|
version '1.2.0'
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
|
|||||||
@@ -2,16 +2,18 @@ package com.synebula.gaea.app.autoconfig.service
|
|||||||
|
|
||||||
import com.synebula.gaea.data.serialization.IObjectMapper
|
import com.synebula.gaea.data.serialization.IObjectMapper
|
||||||
import com.synebula.gaea.domain.repository.IRepository
|
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.IService
|
||||||
import com.synebula.gaea.domain.service.Service
|
import com.synebula.gaea.domain.service.Service
|
||||||
import com.synebula.gaea.domain.service.ServiceDependency
|
|
||||||
import com.synebula.gaea.spring.autoconfig.Proxy
|
import com.synebula.gaea.spring.autoconfig.Proxy
|
||||||
import org.springframework.beans.factory.BeanFactory
|
import org.springframework.beans.factory.BeanFactory
|
||||||
import java.io.InvalidClassException
|
import java.io.InvalidClassException
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
|
|
||||||
class ServiceProxy(
|
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() {
|
) : Proxy() {
|
||||||
|
|
||||||
private var service: IService<*>
|
private var service: IService<*>
|
||||||
@@ -20,18 +22,26 @@ class ServiceProxy(
|
|||||||
// 如果没有实现类, 使用Service类代理
|
// 如果没有实现类, 使用Service类代理
|
||||||
if (implementBeanNames.isEmpty()) {
|
if (implementBeanNames.isEmpty()) {
|
||||||
// 如果没有实现类并且没有ServiceDependency注解, 则抛出异常
|
// 如果没有实现类并且没有ServiceDependency注解, 则抛出异常
|
||||||
if (!this.supertype.declaredAnnotations.any { it.annotationClass == ServiceDependency::class }) {
|
if (!this.supertype.declaredAnnotations.any { it.annotationClass == Domain::class }) {
|
||||||
throw InvalidClassException(
|
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 domain = this.supertype.getDeclaredAnnotation(Domain::class.java)
|
||||||
val repo = this.beanFactory.getBean(serviceDependency.repo.java)
|
|
||||||
|
// repository工厂对象
|
||||||
|
val defaultRepositoryFactory = this.beanFactory.getBean(IRepositoryFactory::class.java)
|
||||||
val mapper = this.beanFactory.getBean(IObjectMapper::class.java)
|
val mapper = this.beanFactory.getBean(IObjectMapper::class.java)
|
||||||
|
|
||||||
val constructor = Service::class.java.getConstructor(
|
val constructor = Service::class.java.getConstructor(
|
||||||
Class::class.java, IRepository::class.java, IObjectMapper::class.java
|
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 {
|
} else {
|
||||||
this.service = this.beanFactory.getBean(implementBeanNames[0]) as IService<*>
|
this.service = this.beanFactory.getBean(implementBeanNames[0]) as IService<*>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,4 +51,16 @@ class MongodbRepoRegister : Register() {
|
|||||||
}
|
}
|
||||||
return result
|
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