Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
c55362c3
S
spring-framework
项目概览
爱吃血肠
/
spring-framework
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
spring-framework
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
c55362c3
编写于
2月 08, 2012
作者:
J
Juergen Hoeller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Provider injection works with generically typed collections of beans as well (SPR-9030)
上级
9a61f36d
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
209 addition
and
39 deletion
+209
-39
org.springframework.beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java
...gframework/beans/factory/config/DependencyDescriptor.java
+49
-19
org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java
...ork/beans/factory/support/DefaultListableBeanFactory.java
+3
-16
org.springframework.beans/src/test/java/org/springframework/beans/factory/annotation/InjectAnnotationBeanPostProcessorTests.java
...ry/annotation/InjectAnnotationBeanPostProcessorTests.java
+133
-4
org.springframework.core/src/main/java/org/springframework/core/MethodParameter.java
...c/main/java/org/springframework/core/MethodParameter.java
+24
-0
未找到文件。
org.springframework.beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java
浏览文件 @
c55362c3
/*
* Copyright 2002-20
09
the original author or authors.
* Copyright 2002-20
12
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.
...
...
@@ -21,6 +21,7 @@ import java.io.ObjectInputStream;
import
java.io.Serializable
;
import
java.lang.annotation.Annotation
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.ParameterizedType
;
import
java.lang.reflect.Type
;
import
org.springframework.core.GenericCollectionTypeResolver
;
...
...
@@ -56,6 +57,8 @@ public class DependencyDescriptor implements Serializable {
private
final
boolean
eager
;
private
int
nestingLevel
=
1
;
private
transient
Annotation
[]
fieldAnnotations
;
...
...
@@ -153,6 +156,13 @@ public class DependencyDescriptor implements Serializable {
}
public
void
increaseNestingLevel
()
{
this
.
nestingLevel
++;
if
(
this
.
methodParameter
!=
null
)
{
this
.
methodParameter
.
increaseNestingLevel
();
}
}
/**
* Initialize parameter name discovery for the underlying method parameter, if any.
* <p>This method does not actually try to retrieve the parameter name at
...
...
@@ -178,15 +188,30 @@ public class DependencyDescriptor implements Serializable {
* @return the declared type (never <code>null</code>)
*/
public
Class
<?>
getDependencyType
()
{
return
(
this
.
field
!=
null
?
this
.
field
.
getType
()
:
this
.
methodParameter
.
getParameterType
());
if
(
this
.
field
!=
null
)
{
if
(
this
.
nestingLevel
>
1
)
{
Type
type
=
this
.
field
.
getGenericType
();
if
(
type
instanceof
ParameterizedType
)
{
Type
arg
=
((
ParameterizedType
)
type
).
getActualTypeArguments
()[
0
];
if
(
arg
instanceof
Class
)
{
return
(
Class
)
arg
;
}
else
if
(
arg
instanceof
ParameterizedType
)
{
arg
=
((
ParameterizedType
)
arg
).
getRawType
();
if
(
arg
instanceof
Class
)
{
return
(
Class
)
arg
;
}
}
}
return
Object
.
class
;
}
else
{
return
this
.
field
.
getType
();
}
}
else
{
return
this
.
methodParameter
.
getNestedParameterType
();
}
/**
* Determine the generic type of the wrapped parameter/field.
* @return the generic type (never <code>null</code>)
*/
public
Type
getGenericDependencyType
()
{
return
(
this
.
field
!=
null
?
this
.
field
.
getGenericType
()
:
this
.
methodParameter
.
getGenericParameterType
());
}
/**
...
...
@@ -195,7 +220,7 @@ public class DependencyDescriptor implements Serializable {
*/
public
Class
<?>
getCollectionType
()
{
return
(
this
.
field
!=
null
?
GenericCollectionTypeResolver
.
getCollectionFieldType
(
this
.
field
)
:
GenericCollectionTypeResolver
.
getCollectionFieldType
(
this
.
field
,
this
.
nestingLevel
)
:
GenericCollectionTypeResolver
.
getCollectionParameterType
(
this
.
methodParameter
));
}
...
...
@@ -205,7 +230,7 @@ public class DependencyDescriptor implements Serializable {
*/
public
Class
<?>
getMapKeyType
()
{
return
(
this
.
field
!=
null
?
GenericCollectionTypeResolver
.
getMapKeyFieldType
(
this
.
field
)
:
GenericCollectionTypeResolver
.
getMapKeyFieldType
(
this
.
field
,
this
.
nestingLevel
)
:
GenericCollectionTypeResolver
.
getMapKeyParameterType
(
this
.
methodParameter
));
}
...
...
@@ -215,7 +240,7 @@ public class DependencyDescriptor implements Serializable {
*/
public
Class
<?>
getMapValueType
()
{
return
(
this
.
field
!=
null
?
GenericCollectionTypeResolver
.
getMapValueFieldType
(
this
.
field
)
:
GenericCollectionTypeResolver
.
getMapValueFieldType
(
this
.
field
,
this
.
nestingLevel
)
:
GenericCollectionTypeResolver
.
getMapValueParameterType
(
this
.
methodParameter
));
}
...
...
@@ -248,7 +273,8 @@ public class DependencyDescriptor implements Serializable {
if
(
this
.
fieldName
!=
null
)
{
this
.
field
=
this
.
declaringClass
.
getDeclaredField
(
this
.
fieldName
);
}
else
if
(
this
.
methodName
!=
null
)
{
else
{
if
(
this
.
methodName
!=
null
)
{
this
.
methodParameter
=
new
MethodParameter
(
this
.
declaringClass
.
getDeclaredMethod
(
this
.
methodName
,
this
.
parameterTypes
),
this
.
parameterIndex
);
}
...
...
@@ -256,6 +282,10 @@ public class DependencyDescriptor implements Serializable {
this
.
methodParameter
=
new
MethodParameter
(
this
.
declaringClass
.
getDeclaredConstructor
(
this
.
parameterTypes
),
this
.
parameterIndex
);
}
for
(
int
i
=
1
;
i
<
this
.
nestingLevel
;
i
++)
{
this
.
methodParameter
.
increaseNestingLevel
();
}
}
}
catch
(
Throwable
ex
)
{
throw
new
IllegalStateException
(
"Could not find original class structure"
,
ex
);
...
...
org.springframework.beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java
浏览文件 @
c55362c3
/*
* Copyright 2002-201
1
the original author or authors.
* Copyright 2002-201
2
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.
...
...
@@ -1000,27 +1000,14 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
private
final
String
beanName
;
private
final
Class
type
;
public
DependencyObjectFactory
(
DependencyDescriptor
descriptor
,
String
beanName
)
{
this
.
descriptor
=
descriptor
;
this
.
beanName
=
beanName
;
this
.
type
=
determineObjectFactoryType
();
}
private
Class
determineObjectFactoryType
()
{
Type
type
=
this
.
descriptor
.
getGenericDependencyType
();
if
(
type
instanceof
ParameterizedType
)
{
Type
arg
=
((
ParameterizedType
)
type
).
getActualTypeArguments
()[
0
];
if
(
arg
instanceof
Class
)
{
return
(
Class
)
arg
;
}
}
return
Object
.
class
;
this
.
descriptor
.
increaseNestingLevel
();
}
public
Object
getObject
()
throws
BeansException
{
return
doResolveDependency
(
this
.
descriptor
,
this
.
type
,
this
.
beanName
,
null
,
null
);
return
doResolveDependency
(
this
.
descriptor
,
this
.
descriptor
.
getDependencyType
()
,
this
.
beanName
,
null
,
null
);
}
}
...
...
org.springframework.beans/src/test/java/org/springframework/beans/factory/annotation/InjectAnnotationBeanPostProcessorTests.java
浏览文件 @
c55362c3
/*
* Copyright 2002-20
09
the original author or authors.
* Copyright 2002-20
12
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.
...
...
@@ -23,7 +23,6 @@ import javax.inject.Inject;
import
javax.inject.Named
;
import
javax.inject.Provider
;
import
static
org
.
junit
.
Assert
.*;
import
org.junit.Test
;
import
test.beans.ITestBean
;
import
test.beans.IndexedTestBean
;
...
...
@@ -40,6 +39,8 @@ import org.springframework.beans.factory.support.GenericBeanDefinition;
import
org.springframework.beans.factory.support.RootBeanDefinition
;
import
org.springframework.util.SerializationTestUtils
;
import
static
org
.
junit
.
Assert
.*;
/**
* Unit tests for {@link org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor}
* processing the JSR-303 {@link javax.inject.Inject} annotation.
...
...
@@ -206,8 +207,8 @@ public class InjectAnnotationBeanPostProcessorTests {
AutowiredAnnotationBeanPostProcessor
bpp
=
new
AutowiredAnnotationBeanPostProcessor
();
bpp
.
setBeanFactory
(
bf
);
bf
.
addBeanPostProcessor
(
bpp
);
bf
.
registerBeanDefinition
(
"annotatedBean"
,
new
RootBeanDefinition
(
ConstructorsCollectionResourceInjectionBean
.
class
));
bf
.
registerBeanDefinition
(
"annotatedBean"
,
new
RootBeanDefinition
(
ConstructorsCollectionResourceInjectionBean
.
class
));
TestBean
tb
=
new
TestBean
();
bf
.
registerSingleton
(
"testBean"
,
tb
);
NestedTestBean
ntb1
=
new
NestedTestBean
();
...
...
@@ -415,6 +416,74 @@ public class InjectAnnotationBeanPostProcessorTests {
bf
.
destroySingletons
();
}
@Test
public
void
testObjectFactoryWithTypedListField
()
throws
Exception
{
DefaultListableBeanFactory
bf
=
new
DefaultListableBeanFactory
();
AutowiredAnnotationBeanPostProcessor
bpp
=
new
AutowiredAnnotationBeanPostProcessor
();
bpp
.
setBeanFactory
(
bf
);
bf
.
addBeanPostProcessor
(
bpp
);
bf
.
registerBeanDefinition
(
"annotatedBean"
,
new
RootBeanDefinition
(
ObjectFactoryListFieldInjectionBean
.
class
));
bf
.
registerBeanDefinition
(
"testBean"
,
new
RootBeanDefinition
(
TestBean
.
class
));
bf
.
setSerializationId
(
"test"
);
ObjectFactoryListFieldInjectionBean
bean
=
(
ObjectFactoryListFieldInjectionBean
)
bf
.
getBean
(
"annotatedBean"
);
assertSame
(
bf
.
getBean
(
"testBean"
),
bean
.
getTestBean
());
bean
=
(
ObjectFactoryListFieldInjectionBean
)
SerializationTestUtils
.
serializeAndDeserialize
(
bean
);
assertSame
(
bf
.
getBean
(
"testBean"
),
bean
.
getTestBean
());
bf
.
destroySingletons
();
}
@Test
public
void
testObjectFactoryWithTypedListMethod
()
throws
Exception
{
DefaultListableBeanFactory
bf
=
new
DefaultListableBeanFactory
();
AutowiredAnnotationBeanPostProcessor
bpp
=
new
AutowiredAnnotationBeanPostProcessor
();
bpp
.
setBeanFactory
(
bf
);
bf
.
addBeanPostProcessor
(
bpp
);
bf
.
registerBeanDefinition
(
"annotatedBean"
,
new
RootBeanDefinition
(
ObjectFactoryListMethodInjectionBean
.
class
));
bf
.
registerBeanDefinition
(
"testBean"
,
new
RootBeanDefinition
(
TestBean
.
class
));
bf
.
setSerializationId
(
"test"
);
ObjectFactoryListMethodInjectionBean
bean
=
(
ObjectFactoryListMethodInjectionBean
)
bf
.
getBean
(
"annotatedBean"
);
assertSame
(
bf
.
getBean
(
"testBean"
),
bean
.
getTestBean
());
bean
=
(
ObjectFactoryListMethodInjectionBean
)
SerializationTestUtils
.
serializeAndDeserialize
(
bean
);
assertSame
(
bf
.
getBean
(
"testBean"
),
bean
.
getTestBean
());
bf
.
destroySingletons
();
}
@Test
public
void
testObjectFactoryWithTypedMapField
()
throws
Exception
{
DefaultListableBeanFactory
bf
=
new
DefaultListableBeanFactory
();
AutowiredAnnotationBeanPostProcessor
bpp
=
new
AutowiredAnnotationBeanPostProcessor
();
bpp
.
setBeanFactory
(
bf
);
bf
.
addBeanPostProcessor
(
bpp
);
bf
.
registerBeanDefinition
(
"annotatedBean"
,
new
RootBeanDefinition
(
ObjectFactoryMapFieldInjectionBean
.
class
));
bf
.
registerBeanDefinition
(
"testBean"
,
new
RootBeanDefinition
(
TestBean
.
class
));
bf
.
setSerializationId
(
"test"
);
ObjectFactoryMapFieldInjectionBean
bean
=
(
ObjectFactoryMapFieldInjectionBean
)
bf
.
getBean
(
"annotatedBean"
);
assertSame
(
bf
.
getBean
(
"testBean"
),
bean
.
getTestBean
());
bean
=
(
ObjectFactoryMapFieldInjectionBean
)
SerializationTestUtils
.
serializeAndDeserialize
(
bean
);
assertSame
(
bf
.
getBean
(
"testBean"
),
bean
.
getTestBean
());
bf
.
destroySingletons
();
}
@Test
public
void
testObjectFactoryWithTypedMapMethod
()
throws
Exception
{
DefaultListableBeanFactory
bf
=
new
DefaultListableBeanFactory
();
AutowiredAnnotationBeanPostProcessor
bpp
=
new
AutowiredAnnotationBeanPostProcessor
();
bpp
.
setBeanFactory
(
bf
);
bf
.
addBeanPostProcessor
(
bpp
);
bf
.
registerBeanDefinition
(
"annotatedBean"
,
new
RootBeanDefinition
(
ObjectFactoryMapMethodInjectionBean
.
class
));
bf
.
registerBeanDefinition
(
"testBean"
,
new
RootBeanDefinition
(
TestBean
.
class
));
bf
.
setSerializationId
(
"test"
);
ObjectFactoryMapMethodInjectionBean
bean
=
(
ObjectFactoryMapMethodInjectionBean
)
bf
.
getBean
(
"annotatedBean"
);
assertSame
(
bf
.
getBean
(
"testBean"
),
bean
.
getTestBean
());
bean
=
(
ObjectFactoryMapMethodInjectionBean
)
SerializationTestUtils
.
serializeAndDeserialize
(
bean
);
assertSame
(
bf
.
getBean
(
"testBean"
),
bean
.
getTestBean
());
bf
.
destroySingletons
();
}
/**
* Verifies that a dependency on a {@link org.springframework.beans.factory.FactoryBean} can be autowired via
* {@link org.springframework.beans.factory.annotation.Autowired @Inject}, specifically addressing the JIRA issue
...
...
@@ -835,6 +904,66 @@ public class InjectAnnotationBeanPostProcessorTests {
}
public
static
class
ObjectFactoryListFieldInjectionBean
implements
Serializable
{
@Inject
private
Provider
<
List
<
TestBean
>>
testBeanFactory
;
public
void
setTestBeanFactory
(
Provider
<
List
<
TestBean
>>
testBeanFactory
)
{
this
.
testBeanFactory
=
testBeanFactory
;
}
public
TestBean
getTestBean
()
{
return
this
.
testBeanFactory
.
get
().
get
(
0
);
}
}
public
static
class
ObjectFactoryListMethodInjectionBean
implements
Serializable
{
private
Provider
<
List
<
TestBean
>>
testBeanFactory
;
@Inject
public
void
setTestBeanFactory
(
Provider
<
List
<
TestBean
>>
testBeanFactory
)
{
this
.
testBeanFactory
=
testBeanFactory
;
}
public
TestBean
getTestBean
()
{
return
this
.
testBeanFactory
.
get
().
get
(
0
);
}
}
public
static
class
ObjectFactoryMapFieldInjectionBean
implements
Serializable
{
@Inject
private
Provider
<
Map
<
String
,
TestBean
>>
testBeanFactory
;
public
void
setTestBeanFactory
(
Provider
<
Map
<
String
,
TestBean
>>
testBeanFactory
)
{
this
.
testBeanFactory
=
testBeanFactory
;
}
public
TestBean
getTestBean
()
{
return
this
.
testBeanFactory
.
get
().
values
().
iterator
().
next
();
}
}
public
static
class
ObjectFactoryMapMethodInjectionBean
implements
Serializable
{
private
Provider
<
Map
<
String
,
TestBean
>>
testBeanFactory
;
@Inject
public
void
setTestBeanFactory
(
Provider
<
Map
<
String
,
TestBean
>>
testBeanFactory
)
{
this
.
testBeanFactory
=
testBeanFactory
;
}
public
TestBean
getTestBean
()
{
return
this
.
testBeanFactory
.
get
().
values
().
iterator
().
next
();
}
}
/**
* Bean with a dependency on a {@link org.springframework.beans.factory.FactoryBean}.
*/
...
...
org.springframework.core/src/main/java/org/springframework/core/MethodParameter.java
浏览文件 @
c55362c3
...
...
@@ -21,6 +21,7 @@ import java.lang.reflect.AnnotatedElement;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.Member
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.ParameterizedType
;
import
java.lang.reflect.Type
;
import
java.lang.reflect.TypeVariable
;
import
java.util.HashMap
;
...
...
@@ -233,6 +234,29 @@ public class MethodParameter {
return
this
.
genericParameterType
;
}
public
Class
<?>
getNestedParameterType
()
{
if
(
this
.
nestingLevel
>
1
)
{
Type
type
=
getGenericParameterType
();
if
(
type
instanceof
ParameterizedType
)
{
Integer
index
=
getTypeIndexForCurrentLevel
();
Type
arg
=
((
ParameterizedType
)
type
).
getActualTypeArguments
()[
index
!=
null
?
index
:
0
];
if
(
arg
instanceof
Class
)
{
return
(
Class
)
arg
;
}
else
if
(
arg
instanceof
ParameterizedType
)
{
arg
=
((
ParameterizedType
)
arg
).
getRawType
();
if
(
arg
instanceof
Class
)
{
return
(
Class
)
arg
;
}
}
}
return
Object
.
class
;
}
else
{
return
getParameterType
();
}
}
/**
* Return the annotations associated with the target method/constructor itself.
*/
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录