mirror of
https://github.com/tursom/TursomServer.git
synced 2025-01-14 14:20:25 +08:00
Delete aop directory
This commit is contained in:
parent
28de77dc79
commit
0fa7a13940
@ -1,5 +0,0 @@
|
||||
dependencies {
|
||||
implementation project(":utils:xml")
|
||||
// 解析XML
|
||||
implementation group: 'dom4j', name: 'dom4j', version: '1.6.1'
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
package cn.tursom.aop
|
||||
|
||||
import cn.tursom.aop.advice.AdviceContent
|
||||
import cn.tursom.aop.aspect.Aspect
|
||||
import java.lang.reflect.InvocationHandler
|
||||
import java.lang.reflect.Method
|
||||
import java.lang.reflect.Proxy
|
||||
|
||||
class ProxyHandler(private val target: Any, private val aspect: Aspect) : InvocationHandler {
|
||||
|
||||
fun getTopBean(): Any {
|
||||
var bean = target
|
||||
while (Proxy.isProxyClass(bean.javaClass)) {
|
||||
val handler = Proxy.getInvocationHandler(bean)
|
||||
if (handler is ProxyHandler)
|
||||
bean = handler.target
|
||||
else break
|
||||
}
|
||||
return bean
|
||||
}
|
||||
|
||||
override fun invoke(proxy: Any?, method: Method, args: Array<out Any>?): Any? {
|
||||
return if (aspect.pointcut.matchMethod(method)) {
|
||||
aspect.advice.invoke(AdviceContent(target, method, args))
|
||||
} else {
|
||||
method.invoke(target, args)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun proxyEnhance(bean: Any, aspect: Aspect): Any {
|
||||
val clazz = bean.javaClass
|
||||
return Proxy.newProxyInstance(
|
||||
clazz.classLoader,
|
||||
clazz.interfaces,
|
||||
ProxyHandler(bean, aspect)
|
||||
)
|
||||
}
|
||||
|
||||
fun getTopBean(target: Any): Any {
|
||||
var bean = target
|
||||
while (Proxy.isProxyClass(bean.javaClass)) {
|
||||
val handler = Proxy.getInvocationHandler(bean)
|
||||
if (handler is ProxyHandler)
|
||||
bean = handler.target
|
||||
else break
|
||||
}
|
||||
return bean
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
package cn.tursom.aop.advice
|
||||
|
||||
interface Advice {
|
||||
operator fun invoke(content: AdviceContent): Any?
|
||||
}
|
||||
|
@ -1,27 +0,0 @@
|
||||
package cn.tursom.aop.advice
|
||||
|
||||
import cn.tursom.aop.ProxyHandler
|
||||
import java.lang.reflect.Method
|
||||
import java.lang.reflect.Proxy
|
||||
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
class AdviceContent(
|
||||
val target: Any,
|
||||
val method: Method,
|
||||
val args: Array<out Any>?
|
||||
) {
|
||||
val bean: Any = if (Proxy.isProxyClass(target.javaClass)) {
|
||||
val handler = Proxy.getInvocationHandler(target)
|
||||
if (handler is ProxyHandler)
|
||||
handler.getTopBean()
|
||||
else target
|
||||
} else target
|
||||
|
||||
fun invoke() {
|
||||
if (args != null) {
|
||||
method.invoke(target, *args)
|
||||
} else {
|
||||
method.invoke(target)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package cn.tursom.aop.aspect
|
||||
|
||||
import cn.tursom.aop.advice.Advice
|
||||
import cn.tursom.aop.pointcut.Pointcut
|
||||
|
||||
interface Aspect {
|
||||
val pointcut: Pointcut
|
||||
val advice: Advice
|
||||
}
|
||||
|
@ -1,6 +0,0 @@
|
||||
package cn.tursom.aop.aspect
|
||||
|
||||
import cn.tursom.aop.advice.Advice
|
||||
import cn.tursom.aop.pointcut.Pointcut
|
||||
|
||||
data class DefaultAspect(override val pointcut: Pointcut, override val advice: Advice) : Aspect
|
@ -1,150 +0,0 @@
|
||||
package cn.tursom.aop.factory
|
||||
|
||||
import cn.tursom.aop.advice.Advice
|
||||
import cn.tursom.aop.aspect.DefaultAspect
|
||||
import cn.tursom.aop.ioc.DefaultIocContainer
|
||||
import cn.tursom.aop.ioc.IocContainer
|
||||
import cn.tursom.aop.pointcut.Pointcut
|
||||
import cn.tursom.aop.pointcut.RegexPointcut
|
||||
import cn.tursom.utils.xml.Xml
|
||||
import org.dom4j.Element
|
||||
import java.io.File
|
||||
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
object IocContainerFactory {
|
||||
/**
|
||||
* example:
|
||||
* <IOC>
|
||||
* <bean class="cn.tursom.Example1" id="exampleBean1"/>
|
||||
* <bean class="cn.tursom.Example2" id="exampleBean2">
|
||||
* <property name="propertyField" value="test"/>
|
||||
* <ref name="refField" id="exampleBean1" />
|
||||
* <bean name="beanField" class="cn.tursom.BeanField" />
|
||||
* </bean>
|
||||
* <aspect>
|
||||
* <advice class="cn.tursom.AdviceExample" />
|
||||
* <advice class="cn.tursom.AdviceExample2" />
|
||||
* <RegexPointcut class="cn\.tursom\.aop\..*" method=".*" />
|
||||
* <pointcut pointcut="RegexPointcut" class="cn\.tursom\.aop\.ioc\..*" method=".*" />
|
||||
* </aspect>
|
||||
* </IOC>
|
||||
*/
|
||||
fun loadFromXml(path: String): IocContainer = loadFromXml(path, Thread.currentThread().contextClassLoader)
|
||||
|
||||
fun loadFromXml(path: String, classLoader: ClassLoader): IocContainer {
|
||||
val element: Element = Xml.saxReader.read(File(path)).rootElement
|
||||
val iocContainer = DefaultIocContainer()
|
||||
element.elements("bean").forEach {
|
||||
if (it !is Element) return@forEach
|
||||
val id = it.attribute("id").value
|
||||
val bean = getXmlBean(it, classLoader, iocContainer)
|
||||
iocContainer.addBean(id, bean)
|
||||
}
|
||||
element.elements("aspect").forEach {
|
||||
if (it !is Element) return@forEach
|
||||
val advices = getXmlAdvices(it, classLoader)
|
||||
val pointcuts = getXmlPointCuts(it)
|
||||
advices.forEach { advice ->
|
||||
pointcuts.forEach { pointcut ->
|
||||
iocContainer.addAspect(DefaultAspect(pointcut, advice))
|
||||
}
|
||||
}
|
||||
}
|
||||
return iocContainer
|
||||
}
|
||||
|
||||
fun getXmlPointCuts(root: Element): List<Pointcut> {
|
||||
val pointcuts = ArrayList<Pointcut>()
|
||||
root.elements("RegexPointcut").forEach {
|
||||
if (it !is Element) return@forEach
|
||||
val clazz = it.attributeValue("class")
|
||||
val method = it.attributeValue("method")
|
||||
pointcuts.add(RegexPointcut(clazz, method))
|
||||
}
|
||||
root.elements().forEach {
|
||||
if (it !is Element) return@forEach
|
||||
val clazz = it.attributeValue("class")
|
||||
val method = it.attributeValue("method")
|
||||
pointcuts.add(RegexPointcut(clazz, method))
|
||||
}
|
||||
return pointcuts
|
||||
}
|
||||
|
||||
fun getXmlAdvices(root: Element, classLoader: ClassLoader): List<Advice> {
|
||||
val advices = ArrayList<Advice>()
|
||||
root.elements("advice").forEach {
|
||||
if (it !is Element) return@forEach
|
||||
val clazzName = it.attributeValue("class")
|
||||
val clazz = classLoader.loadClass(clazzName)
|
||||
advices.add(clazz.newInstance() as Advice)
|
||||
}
|
||||
return advices
|
||||
}
|
||||
|
||||
fun getXmlBean(root: Element, classLoader: ClassLoader, iocContainer: IocContainer): Any {
|
||||
val clazz = classLoader.loadClass(root.attribute("class").value)
|
||||
val bean = clazz.newInstance()
|
||||
root.elements()?.forEach subForEach@{ sub ->
|
||||
if (sub !is Element) return@subForEach
|
||||
when (sub.name) {
|
||||
"property" -> {
|
||||
val name = sub.attributeValue("name")
|
||||
val value = sub.attributeValue("value")
|
||||
val field = clazz.getDeclaredField(name)
|
||||
field.isAccessible = true
|
||||
field.set(bean, value)
|
||||
}
|
||||
"ref" -> {
|
||||
val name = sub.attributeValue("name")
|
||||
val refId = sub.attributeValue("id")
|
||||
val field = clazz.getDeclaredField(name)
|
||||
field.isAccessible = true
|
||||
field.set(bean, iocContainer[refId])
|
||||
}
|
||||
"bean" -> {
|
||||
val name = sub.attributeValue("name")
|
||||
val field = clazz.getDeclaredField(name)
|
||||
field.isAccessible = true
|
||||
field.set(bean, getXmlBean(sub, classLoader, iocContainer))
|
||||
}
|
||||
}
|
||||
}
|
||||
return bean
|
||||
}
|
||||
|
||||
/**
|
||||
* example:
|
||||
* {
|
||||
* "beans": [
|
||||
* {
|
||||
* "id": "exampleBean1",
|
||||
* "class": "cn.tursom.Example1"
|
||||
* },
|
||||
* {
|
||||
* "id": "exampleBean2",
|
||||
* "class": "cn.tursom.Example2",
|
||||
* "properties": [
|
||||
* {
|
||||
* "style": "property",
|
||||
* "name": "propertyField",
|
||||
* "value": "test"
|
||||
* },
|
||||
* {
|
||||
* "style": "ref",
|
||||
* "name": "refField",
|
||||
* "id": "exampleBean1"
|
||||
* },
|
||||
* {
|
||||
* "style": "bean",
|
||||
* "id": "refFiled",
|
||||
* "class": "cn.tursom.BeanField"
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
*/
|
||||
fun loadFromJson(json: String): IocContainer {
|
||||
TODO()
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
package cn.tursom.aop.ioc
|
||||
|
||||
import cn.tursom.aop.aspect.Aspect
|
||||
import cn.tursom.aop.ProxyHandler
|
||||
import java.lang.reflect.Proxy
|
||||
|
||||
class DefaultIocContainer : IocContainer {
|
||||
private val benDefinitionMap = HashMap<String, Class<*>>()
|
||||
private val beanMap = HashMap<String, Any>()
|
||||
private val aspectSet: java.util.AbstractSet<Aspect> = HashSet<Aspect>()
|
||||
|
||||
override val aspects: Set<Aspect> get() = aspectSet
|
||||
|
||||
override fun addBeanDefinition(beanName: String, clazz: Class<*>) {
|
||||
benDefinitionMap[beanName] = clazz
|
||||
}
|
||||
|
||||
override fun addBean(beanName: String, bean: Any) {
|
||||
beanMap[beanName] = proxyEnhance(bean)
|
||||
}
|
||||
|
||||
override fun getBean(beanName: String): Any {
|
||||
return beanMap[beanName] ?: run {
|
||||
val bean = createInstance(beanName)
|
||||
val proxyBean = proxyEnhance(bean)
|
||||
beanMap[beanName] = proxyBean
|
||||
proxyBean
|
||||
}
|
||||
}
|
||||
|
||||
private fun proxyEnhance(bean: Any): Any {
|
||||
val clazz = getTopBean(bean).javaClass
|
||||
var enhanceBean = bean
|
||||
aspectSet.forEach {
|
||||
if (it.pointcut.matchClass(clazz)) {
|
||||
enhanceBean = ProxyHandler.proxyEnhance(enhanceBean, it)
|
||||
}
|
||||
}
|
||||
return enhanceBean
|
||||
}
|
||||
|
||||
private fun createInstance(beanName: String): Any {
|
||||
return (benDefinitionMap[beanName] ?: throw NullPointerException()).newInstance()
|
||||
}
|
||||
|
||||
override fun addAspect(aspect: Aspect) {
|
||||
if (aspectSet.contains(aspect)) return
|
||||
|
||||
aspectSet.add(aspect)
|
||||
beanMap.forEach { (t, u) ->
|
||||
val bean = getTopBean(u)
|
||||
if (aspect.pointcut.matchClass(bean.javaClass)) {
|
||||
beanMap[t] = ProxyHandler.proxyEnhance(u, aspect)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun getTopBean(bean: Any): Any {
|
||||
return if (Proxy.isProxyClass(bean.javaClass)) {
|
||||
val handler = Proxy.getInvocationHandler(bean)
|
||||
if (handler is ProxyHandler) handler.getTopBean()
|
||||
else bean
|
||||
} else {
|
||||
bean
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +0,0 @@
|
||||
package cn.tursom.aop.ioc
|
||||
|
||||
import cn.tursom.aop.aspect.Aspect
|
||||
|
||||
interface IocContainer {
|
||||
val aspects: Set<Aspect>
|
||||
|
||||
fun addAspect(aspect: Aspect)
|
||||
fun addBeanDefinition(beanName: String, clazz: Class<*>)
|
||||
fun addBean(beanName: String, bean: Any)
|
||||
operator fun set(beanName: String, bean: Any) = addBean(beanName, bean)
|
||||
fun getBean(beanName: String): Any
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
operator fun <T> get(beanName: String): T = getBean(beanName) as T
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
package cn.tursom.aop.pointcut
|
||||
|
||||
import java.lang.reflect.Method
|
||||
|
||||
interface Pointcut {
|
||||
fun matchClass(clazz: Class<*>): Boolean
|
||||
fun matchMethod(method: Method): Boolean
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
package cn.tursom.aop.pointcut
|
||||
|
||||
import java.lang.reflect.Method
|
||||
|
||||
data class RegexPointcut(
|
||||
private val classRegex: Regex,
|
||||
private val methodRegex: Regex
|
||||
) : Pointcut {
|
||||
constructor(classRegex: String, methodRegex: String) : this(classRegex.toRegex(), methodRegex.toRegex())
|
||||
|
||||
override fun matchClass(clazz: Class<*>) = classRegex.matches(clazz.name)
|
||||
override fun matchMethod(method: Method) = methodRegex.matches(method.name)
|
||||
}
|
Loading…
Reference in New Issue
Block a user