-
Notifications
You must be signed in to change notification settings - Fork 0
/
MyComponentProviderTest.java
89 lines (81 loc) · 3.52 KB
/
MyComponentProviderTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package org.example;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
public class MyComponentProviderTest {
private AnnotationConfigApplicationContext context;
@Before
public void setUp() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.setCacheBeanMetadata(false); // <---------- If it is false @lookup can't create proxy !
context = new AnnotationConfigApplicationContext(beanFactory);
context.scan("org.example");
context.refresh();
}
/**
* 1)
* public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
* ...
* protected RootBeanDefinition getMergedBeanDefinition(
* ...
* if (containingBd == null && isCacheBeanMetadata()) {
* this.mergedBeanDefinitions.put(beanName, mbd); <---------- is always empty
* }
* ...
* }
* ...
* }
*
* 2) Then here
* public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
* implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
* ...
* public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
* throws BeanCreationException {
* ...
* ReflectionUtils.doWithLocalMethods(targetClass, method -> {
* Lookup lookup = method.getAnnotation(Lookup.class);
* if (lookup != null) {
* Assert.state(this.beanFactory != null, "No BeanFactory available");
* LookupOverride override = new LookupOverride(method, lookup.value());
* try {
* RootBeanDefinition mbd = (RootBeanDefinition)
* this.beanFactory.getMergedBeanDefinition(beanName); <---------- always returns a new object even for the same "beanName"
* mbd.getMethodOverrides().addOverride(override); <---------- and we lose this "override"
* }
* catch (NoSuchBeanDefinitionException ex) {
* throw new BeanCreationException(beanName,
* "Cannot apply @Lookup to beans without corresponding bean definition");
* }* }
* });
* ...
* }
* ...
* }
*
* 3) as a result
* public class SimpleInstantiationStrategy implements InstantiationStrategy {
* ...
* public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
* ...
* if (!bd.hasMethodOverrides()) { <---------- will be false
* ...
* }
* else { <---------- will not generate CGLIB subclass
* // Must generate CGLIB subclass.
* return instantiateWithMethodInjection(bd, beanName, owner);
* }*
* }
* ...
* }
*/
@Test
public void testThatLookupDoesWork() {
MyComponentProvider provider = context.getBean(MyComponentProvider.class);
assertNotEquals(MyComponentProvider.class, provider.getClass());
assertNotNull(provider.get());
}
}