Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
嗝屁小孩纸
guide-rpc-framework
提交
f467b64a
G
guide-rpc-framework
项目概览
嗝屁小孩纸
/
guide-rpc-framework
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
1
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
guide-rpc-framework
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
f467b64a
编写于
9月 02, 2020
作者:
G
guide
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[refractor]RpcReference annotation
上级
8c7273f1
变更
6
显示空白变更内容
内联
并排
Showing
6 changed file
with
87 addition
and
196 deletion
+87
-196
README-EN.md
README-EN.md
+24
-3
README.md
README.md
+23
-3
rpc-framework-simple/src/main/java/github/javaguide/annotation/RpcReference.java
...c/main/java/github/javaguide/annotation/RpcReference.java
+7
-3
rpc-framework-simple/src/main/java/github/javaguide/spring/CustomScannerRegistrar.java
.../java/github/javaguide/spring/CustomScannerRegistrar.java
+2
-9
rpc-framework-simple/src/main/java/github/javaguide/spring/ReferenceAnnotationBeanPostProcessor.java
...avaguide/spring/ReferenceAnnotationBeanPostProcessor.java
+0
-177
rpc-framework-simple/src/main/java/github/javaguide/spring/SpringBeanPostProcessor.java
...java/github/javaguide/spring/SpringBeanPostProcessor.java
+31
-1
未找到文件。
README-EN.md
浏览文件 @
f467b64a
...
...
@@ -160,11 +160,32 @@ public class NettyServerMain {
### Client(srvice consumer)
```
java
@Component
public
class
HelloController
{
@RpcReference
(
version
=
"version1"
,
group
=
"test1"
)
private
HelloService
helloService
;
public
void
test
()
throws
InterruptedException
{
String
hello
=
this
.
helloService
.
hello
(
new
Hello
(
"111"
,
"222"
));
//如需使用 assert 断言,需要在 VM options 添加参数:-ea
assert
"Hello description is 222"
.
equals
(
hello
);
Thread
.
sleep
(
12000
);
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
System
.
out
.
println
(
helloService
.
hello
(
new
Hello
(
"111"
,
"222"
)));
}
}
}
```
```
java
ClientTransport
rpcClient
=
new
NettyClientTranspor
t
();
ClientTransport
clientTransport
=
new
SocketRpcClien
t
();
RpcServiceProperties
rpcServiceProperties
=
RpcServiceProperties
.
builder
()
.
group
(
"test1"
).
version
(
"version1
"
).
build
();
RpcClientProxy
rpcClientProxy
=
new
RpcClientProxy
(
rpcClien
t
,
rpcServiceProperties
);
.
group
(
"test2"
).
version
(
"version2
"
).
build
();
RpcClientProxy
rpcClientProxy
=
new
RpcClientProxy
(
clientTranspor
t
,
rpcServiceProperties
);
HelloService
helloService
=
rpcClientProxy
.
getProxy
(
HelloService
.
class
);
String
hello
=
helloService
.
hello
(
new
Hello
(
"111"
,
"222"
));
System
.
out
.
println
(
hello
);
```
\ No newline at end of file
README.md
浏览文件 @
f467b64a
...
...
@@ -201,12 +201,32 @@ public class NettyServerMain {
### 服务消费端
```
java
ClientTransport
rpcClient
=
new
NettyClientTransport
();
@Component
public
class
HelloController
{
@RpcReference
(
version
=
"version1"
,
group
=
"test1"
)
private
HelloService
helloService
;
public
void
test
()
throws
InterruptedException
{
String
hello
=
this
.
helloService
.
hello
(
new
Hello
(
"111"
,
"222"
));
//如需使用 assert 断言,需要在 VM options 添加参数:-ea
assert
"Hello description is 222"
.
equals
(
hello
);
Thread
.
sleep
(
12000
);
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
System
.
out
.
println
(
helloService
.
hello
(
new
Hello
(
"111"
,
"222"
)));
}
}
}
```
```
java
ClientTransport
clientTransport
=
new
SocketRpcClient
();
RpcServiceProperties
rpcServiceProperties
=
RpcServiceProperties
.
builder
()
.
group
(
"test1"
).
version
(
"version1
"
).
build
();
RpcClientProxy
rpcClientProxy
=
new
RpcClientProxy
(
rpcClien
t
,
rpcServiceProperties
);
.
group
(
"test2"
).
version
(
"version2
"
).
build
();
RpcClientProxy
rpcClientProxy
=
new
RpcClientProxy
(
clientTranspor
t
,
rpcServiceProperties
);
HelloService
helloService
=
rpcClientProxy
.
getProxy
(
HelloService
.
class
);
String
hello
=
helloService
.
hello
(
new
Hello
(
"111"
,
"222"
));
System
.
out
.
println
(
hello
);
```
## 相关问题
...
...
rpc-framework-simple/src/main/java/github/javaguide/annotation/RpcReference.java
浏览文件 @
f467b64a
package
github.javaguide.annotation
;
import
github.javaguide.spring.ReferenceAnnotationBeanPostProcessor
;
import
org.springframework.stereotype.Component
;
import
java.lang.annotation.*
;
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
;
/**
* RPC reference annotation, autowire the service implementation class
*
* @author smile2coder
* @see ReferenceAnnotationBeanPostProcessor
*/
@Documented
@Retention
(
RetentionPolicy
.
RUNTIME
)
...
...
rpc-framework-simple/src/main/java/github/javaguide/spring/CustomScannerRegistrar.java
浏览文件 @
f467b64a
...
...
@@ -3,14 +3,9 @@ package github.javaguide.spring;
import
github.javaguide.annotation.RpcScan
;
import
github.javaguide.annotation.RpcService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.MutablePropertyValues
;
import
org.springframework.beans.factory.config.BeanDefinition
;
import
org.springframework.beans.factory.config.ConstructorArgumentValues
;
import
org.springframework.beans.factory.support.BeanDefinitionRegistry
;
import
org.springframework.beans.factory.support.RootBeanDefinition
;
import
org.springframework.context.ResourceLoaderAware
;
import
org.springframework.context.annotation.ImportBeanDefinitionRegistrar
;
import
org.springframework.core.ResolvableType
;
import
org.springframework.core.annotation.AnnotationAttributes
;
import
org.springframework.core.io.ResourceLoader
;
import
org.springframework.core.type.AnnotationMetadata
;
...
...
@@ -57,11 +52,9 @@ public class CustomScannerRegistrar implements ImportBeanDefinitionRegistrar, Re
}
int
springBeanAmount
=
springBeanScanner
.
scan
(
SPRING_BEAN_BASE_PACKAGE
);
log
.
info
(
"springBeanScanner扫描的数量 [{}]"
,
springBeanAmount
);
int
scan
Count
=
rpcServiceScanner
.
scan
(
rpcScanBasePackages
);
log
.
info
(
"rpcServiceScanner扫描的数量 [{}]"
,
scan
Count
);
int
rpcService
Count
=
rpcServiceScanner
.
scan
(
rpcScanBasePackages
);
log
.
info
(
"rpcServiceScanner扫描的数量 [{}]"
,
rpcService
Count
);
beanDefinitionRegistry
.
registerBeanDefinition
(
ReferenceAnnotationBeanPostProcessor
.
BEAN_NAME
,
new
RootBeanDefinition
(
ReferenceAnnotationBeanPostProcessor
.
class
));
}
}
rpc-framework-simple/src/main/java/github/javaguide/spring/ReferenceAnnotationBeanPostProcessor.java
已删除
100644 → 0
浏览文件 @
8c7273f1
package
github.javaguide.spring
;
import
github.javaguide.annotation.RpcReference
;
import
github.javaguide.entity.RpcServiceProperties
;
import
github.javaguide.extension.ExtensionLoader
;
import
github.javaguide.proxy.RpcClientProxy
;
import
github.javaguide.registry.ServiceDiscovery
;
import
github.javaguide.remoting.transport.ClientTransport
;
import
github.javaguide.remoting.transport.netty.client.NettyClientTransport
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.PropertyValues
;
import
org.springframework.beans.factory.BeanCreationException
;
import
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
;
import
org.springframework.beans.factory.annotation.InjectionMetadata
;
import
org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter
;
import
org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor
;
import
org.springframework.beans.factory.support.RootBeanDefinition
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.ApplicationContextAware
;
import
org.springframework.core.BridgeMethodResolver
;
import
org.springframework.core.annotation.AnnotationAttributes
;
import
org.springframework.core.annotation.AnnotationUtils
;
import
org.springframework.core.annotation.MergedAnnotation
;
import
org.springframework.core.annotation.MergedAnnotations
;
import
org.springframework.lang.Nullable
;
import
org.springframework.util.ClassUtils
;
import
org.springframework.util.ReflectionUtils
;
import
org.springframework.util.StringUtils
;
import
java.beans.PropertyDescriptor
;
import
java.lang.annotation.Annotation
;
import
java.lang.reflect.*
;
import
java.util.*
;
import
java.util.concurrent.ConcurrentHashMap
;
/**
* @author smile2coder
* @
*/
@Slf4j
public
class
ReferenceAnnotationBeanPostProcessor
extends
InstantiationAwareBeanPostProcessorAdapter
implements
MergedBeanDefinitionPostProcessor
,
ApplicationContextAware
{
public
static
final
String
BEAN_NAME
=
"referenceAnnotationBeanPostProcessor"
;
private
String
version
=
"version"
;
private
String
group
=
"group"
;
private
ApplicationContext
applicationContext
;
private
ClientTransport
rpcClient
;
private
final
Set
<
Class
<?
extends
Annotation
>>
annotationTypes
=
new
LinkedHashSet
<>(
1
);
private
final
Map
<
String
,
InjectionMetadata
>
injectionMetadataCache
=
new
ConcurrentHashMap
<>(
256
);
public
ReferenceAnnotationBeanPostProcessor
()
{
this
.
annotationTypes
.
add
(
RpcReference
.
class
);
this
.
rpcClient
=
ExtensionLoader
.
getExtensionLoader
(
ClientTransport
.
class
).
getExtension
(
"nettyClientTransport"
);
}
@Override
public
void
setApplicationContext
(
ApplicationContext
applicationContext
)
throws
BeansException
{
this
.
applicationContext
=
applicationContext
;
}
@Override
public
void
postProcessMergedBeanDefinition
(
RootBeanDefinition
beanDefinition
,
Class
<?>
beanType
,
String
beanName
)
{
InjectionMetadata
metadata
=
findAutowiringMetadata
(
beanName
,
beanType
,
null
);
metadata
.
checkConfigMembers
(
beanDefinition
);
}
private
InjectionMetadata
findAutowiringMetadata
(
String
beanName
,
Class
<?>
clazz
,
PropertyValues
pvs
)
{
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String
cacheKey
=
(
StringUtils
.
hasLength
(
beanName
)
?
beanName
:
clazz
.
getName
());
// Quick check on the concurrent map first, with minimal locking.
InjectionMetadata
metadata
=
this
.
injectionMetadataCache
.
get
(
cacheKey
);
if
(
InjectionMetadata
.
needsRefresh
(
metadata
,
clazz
))
{
synchronized
(
this
.
injectionMetadataCache
)
{
metadata
=
this
.
injectionMetadataCache
.
get
(
cacheKey
);
if
(
InjectionMetadata
.
needsRefresh
(
metadata
,
clazz
))
{
if
(
metadata
!=
null
)
{
metadata
.
clear
(
pvs
);
}
metadata
=
buildAutowiringMetadata
(
clazz
);
this
.
injectionMetadataCache
.
put
(
cacheKey
,
metadata
);
}
}
}
return
metadata
;
}
private
InjectionMetadata
buildAutowiringMetadata
(
final
Class
<?>
clazz
)
{
List
<
InjectionMetadata
.
InjectedElement
>
elements
=
new
ArrayList
<>();
Class
<?>
targetClass
=
clazz
;
do
{
final
List
<
InjectionMetadata
.
InjectedElement
>
currElements
=
new
ArrayList
<>();
ReflectionUtils
.
doWithLocalFields
(
targetClass
,
field
->
{
MergedAnnotation
<?>
ann
=
findReferenceAnnotation
(
field
);
if
(
ann
!=
null
)
{
if
(
Modifier
.
isStatic
(
field
.
getModifiers
()))
{
if
(
log
.
isInfoEnabled
())
{
log
.
info
(
"Autowired annotation is not supported on static fields: "
+
field
);
}
return
;
}
AnnotationAttributes
annotationAttributes
=
(
AnnotationAttributes
)
ann
.
asMap
(
mergedAnnotation
->
new
AnnotationAttributes
(
mergedAnnotation
.
getType
()));
String
version
=
annotationAttributes
.
getString
(
this
.
version
);
String
group
=
annotationAttributes
.
getString
(
this
.
group
);
currElements
.
add
(
new
ReferenceFieldElement
(
field
,
version
,
group
));
}
});
elements
.
addAll
(
0
,
currElements
);
targetClass
=
targetClass
.
getSuperclass
();
}
while
(
targetClass
!=
null
&&
targetClass
!=
Object
.
class
);
return
InjectionMetadata
.
forElements
(
elements
,
clazz
);
}
@Nullable
private
MergedAnnotation
<?>
findReferenceAnnotation
(
AccessibleObject
ao
)
{
MergedAnnotations
annotations
=
MergedAnnotations
.
from
(
ao
);
for
(
Class
<?
extends
Annotation
>
type
:
this
.
annotationTypes
)
{
MergedAnnotation
<?>
annotation
=
annotations
.
get
(
type
);
if
(
annotation
.
isPresent
())
{
return
annotation
;
}
}
return
null
;
}
@Override
public
PropertyValues
postProcessProperties
(
PropertyValues
pvs
,
Object
bean
,
String
beanName
)
throws
BeansException
{
InjectionMetadata
metadata
=
findAutowiringMetadata
(
beanName
,
bean
.
getClass
(),
pvs
);
try
{
metadata
.
inject
(
bean
,
beanName
,
pvs
);
}
catch
(
BeanCreationException
ex
)
{
throw
ex
;
}
catch
(
Throwable
ex
)
{
throw
new
BeanCreationException
(
beanName
,
"Injection of reference dependencies failed"
,
ex
);
}
return
pvs
;
}
private
class
ReferenceFieldElement
extends
InjectionMetadata
.
InjectedElement
{
private
String
version
;
private
String
group
;
protected
ReferenceFieldElement
(
Member
member
,
String
version
,
String
group
)
{
super
(
member
,
null
);
this
.
version
=
version
;
this
.
group
=
group
;
}
@Override
protected
void
inject
(
Object
target
,
String
requestingBeanName
,
PropertyValues
pvs
)
throws
Throwable
{
Field
field
=
(
Field
)
this
.
member
;
RpcServiceProperties
rpcServiceProperties
=
RpcServiceProperties
.
builder
()
.
group
(
group
).
version
(
version
).
build
();
RpcClientProxy
rpcClientProxy
=
new
RpcClientProxy
(
rpcClient
,
rpcServiceProperties
);
Object
value
=
rpcClientProxy
.
getProxy
(
field
.
getType
());
if
(
value
!=
null
)
{
ReflectionUtils
.
makeAccessible
(
field
);
field
.
set
(
target
,
value
);
}
}
}
}
rpc-framework-simple/src/main/java/github/javaguide/spring/SpringBeanPostProcessor.java
浏览文件 @
f467b64a
package
github.javaguide.spring
;
import
github.javaguide.annotation.RpcReference
;
import
github.javaguide.annotation.RpcService
;
import
github.javaguide.entity.RpcServiceProperties
;
import
github.javaguide.extension.ExtensionLoader
;
import
github.javaguide.factory.SingletonFactory
;
import
github.javaguide.provider.ServiceProvider
;
import
github.javaguide.provider.ServiceProviderImpl
;
import
github.javaguide.proxy.RpcClientProxy
;
import
github.javaguide.remoting.transport.ClientTransport
;
import
lombok.SneakyThrows
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.config.BeanPostProcessor
;
import
org.springframework.stereotype.Component
;
import
java.lang.reflect.Field
;
/**
* call this method before creating the bean to see if the class is annotated
*
...
...
@@ -22,9 +28,11 @@ import org.springframework.stereotype.Component;
public
class
SpringBeanPostProcessor
implements
BeanPostProcessor
{
private
final
ServiceProvider
serviceProvider
;
private
final
ClientTransport
rpcClient
;
public
SpringBeanPostProcessor
()
{
serviceProvider
=
SingletonFactory
.
getInstance
(
ServiceProviderImpl
.
class
);
this
.
serviceProvider
=
SingletonFactory
.
getInstance
(
ServiceProviderImpl
.
class
);
this
.
rpcClient
=
ExtensionLoader
.
getExtensionLoader
(
ClientTransport
.
class
).
getExtension
(
"nettyClientTransport"
);
}
@SneakyThrows
...
...
@@ -42,4 +50,26 @@ public class SpringBeanPostProcessor implements BeanPostProcessor {
return
bean
;
}
@Override
public
Object
postProcessAfterInitialization
(
Object
bean
,
String
beanName
)
throws
BeansException
{
Class
<?>
targetClass
=
bean
.
getClass
();
Field
[]
declaredFields
=
targetClass
.
getDeclaredFields
();
for
(
Field
declaredField
:
declaredFields
)
{
RpcReference
rpcReference
=
declaredField
.
getAnnotation
(
RpcReference
.
class
);
if
(
rpcReference
!=
null
)
{
RpcServiceProperties
rpcServiceProperties
=
RpcServiceProperties
.
builder
()
.
group
(
rpcReference
.
group
()).
version
(
rpcReference
.
version
()).
build
();
RpcClientProxy
rpcClientProxy
=
new
RpcClientProxy
(
rpcClient
,
rpcServiceProperties
);
Object
clientProxy
=
rpcClientProxy
.
getProxy
(
declaredField
.
getType
());
declaredField
.
setAccessible
(
true
);
try
{
declaredField
.
set
(
bean
,
clientProxy
);
}
catch
(
IllegalAccessException
e
)
{
e
.
printStackTrace
();
}
}
}
return
bean
;
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录