View Javadoc
1   /*
2    * Copyright 2002-2013 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.context.annotation.configuration;
18  
19  import java.lang.annotation.Retention;
20  import java.lang.annotation.RetentionPolicy;
21  
22  import org.junit.Test;
23  
24  import org.springframework.beans.factory.annotation.Autowired;
25  import org.springframework.beans.factory.annotation.Qualifier;
26  import org.springframework.beans.factory.support.RootBeanDefinition;
27  import org.springframework.context.annotation.AnnotationConfigApplicationContext;
28  import org.springframework.context.annotation.Bean;
29  import org.springframework.context.annotation.Configuration;
30  import org.springframework.context.annotation.Lazy;
31  import org.springframework.context.annotation.Scope;
32  import org.springframework.context.annotation.ScopedProxyMode;
33  import org.springframework.stereotype.Component;
34  import org.springframework.tests.sample.beans.NestedTestBean;
35  import org.springframework.tests.sample.beans.TestBean;
36  
37  import static org.hamcrest.CoreMatchers.*;
38  import static org.junit.Assert.*;
39  
40  /**
41   * Tests proving that @Qualifier annotations work when used
42   * with @Configuration classes on @Bean methods.
43   *
44   * @author Chris Beams
45   * @author Juergen Hoeller
46   */
47  public class BeanMethodQualificationTests {
48  
49  	@Test
50  	public void testStandard() {
51  		AnnotationConfigApplicationContext ctx =
52  				new AnnotationConfigApplicationContext(StandardConfig.class, StandardPojo.class);
53  		assertFalse(ctx.getBeanFactory().containsSingleton("testBean1"));
54  		StandardPojo pojo = ctx.getBean(StandardPojo.class);
55  		assertThat(pojo.testBean.getName(), equalTo("interesting"));
56  		assertThat(pojo.testBean2.getName(), equalTo("boring"));
57  	}
58  
59  	@Test
60  	public void testScoped() {
61  		AnnotationConfigApplicationContext ctx =
62  				new AnnotationConfigApplicationContext(ScopedConfig.class, StandardPojo.class);
63  		assertFalse(ctx.getBeanFactory().containsSingleton("testBean1"));
64  		StandardPojo pojo = ctx.getBean(StandardPojo.class);
65  		assertThat(pojo.testBean.getName(), equalTo("interesting"));
66  		assertThat(pojo.testBean2.getName(), equalTo("boring"));
67  	}
68  
69  	@Test
70  	public void testScopedProxy() {
71  		AnnotationConfigApplicationContext ctx =
72  				new AnnotationConfigApplicationContext(ScopedProxyConfig.class, StandardPojo.class);
73  		assertTrue(ctx.getBeanFactory().containsSingleton("testBean1"));  // a shared scoped proxy
74  		StandardPojo pojo = ctx.getBean(StandardPojo.class);
75  		assertThat(pojo.testBean.getName(), equalTo("interesting"));
76  		assertThat(pojo.testBean2.getName(), equalTo("boring"));
77  	}
78  
79  	@Test
80  	public void testCustom() {
81  		AnnotationConfigApplicationContext ctx =
82  				new AnnotationConfigApplicationContext(CustomConfig.class, CustomPojo.class);
83  		assertFalse(ctx.getBeanFactory().containsSingleton("testBean1"));
84  		CustomPojo pojo = ctx.getBean(CustomPojo.class);
85  		assertThat(pojo.testBean.getName(), equalTo("interesting"));
86  	}
87  
88  	@Test
89  	public void testCustomWithAsm() {
90  		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
91  		ctx.registerBeanDefinition("customConfig", new RootBeanDefinition(CustomConfig.class.getName()));
92  		RootBeanDefinition customPojo = new RootBeanDefinition(CustomPojo.class.getName());
93  		customPojo.setLazyInit(true);
94  		ctx.registerBeanDefinition("customPojo", customPojo);
95  		ctx.refresh();
96  		assertFalse(ctx.getBeanFactory().containsSingleton("testBean1"));
97  		CustomPojo pojo = ctx.getBean(CustomPojo.class);
98  		assertThat(pojo.testBean.getName(), equalTo("interesting"));
99  	}
100 
101 	@Test
102 	public void testCustomWithAttributeOverride() {
103 		AnnotationConfigApplicationContext ctx =
104 				new AnnotationConfigApplicationContext(CustomConfigWithAttributeOverride.class, CustomPojo.class);
105 		assertFalse(ctx.getBeanFactory().containsSingleton("testBeanX"));
106 		CustomPojo pojo = ctx.getBean(CustomPojo.class);
107 		assertThat(pojo.testBean.getName(), equalTo("interesting"));
108 	}
109 
110 
111 	@Configuration
112 	static class StandardConfig {
113 
114 		@Bean @Qualifier("interesting") @Lazy
115 		public TestBean testBean1() {
116 			return new TestBean("interesting");
117 		}
118 
119 		@Bean @Boring
120 		public TestBean testBean2() {
121 			return new TestBean("boring");
122 		}
123 	}
124 
125 	@Configuration
126 	static class ScopedConfig {
127 
128 		@Bean @Qualifier("interesting") @Scope("prototype")
129 		public TestBean testBean1() {
130 			return new TestBean("interesting");
131 		}
132 
133 		@Bean @Boring @Scope("prototype")
134 		public TestBean testBean2() {
135 			return new TestBean("boring");
136 		}
137 	}
138 
139 	@Configuration
140 	static class ScopedProxyConfig {
141 
142 		@Bean @Qualifier("interesting") @Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS)
143 		public TestBean testBean1() {
144 			return new TestBean("interesting");
145 		}
146 
147 		@Bean @Boring @Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS)
148 		public TestBean testBean2() {
149 			return new TestBean("boring");
150 		}
151 	}
152 
153 	@Component @Lazy
154 	static class StandardPojo {
155 
156 		@Autowired @Qualifier("interesting") TestBean testBean;
157 
158 		@Autowired @Boring TestBean testBean2;
159 	}
160 
161 	@Qualifier
162 	@Retention(RetentionPolicy.RUNTIME)
163 	public @interface Boring {
164 	}
165 
166 	@Configuration
167 	static class CustomConfig {
168 
169 		@InterestingBean
170 		public TestBean testBean1() {
171 			return new TestBean("interesting");
172 		}
173 
174 		@Bean @Qualifier("boring")
175 		public TestBean testBean2() {
176 			return new TestBean("boring");
177 		}
178 	}
179 
180 	@Configuration
181 	static class CustomConfigWithAttributeOverride {
182 
183 		@InterestingBeanWithName(name="testBeanX")
184 		public TestBean testBean1() {
185 			return new TestBean("interesting");
186 		}
187 
188 		@Bean @Qualifier("boring")
189 		public TestBean testBean2() {
190 			return new TestBean("boring");
191 		}
192 	}
193 
194 	@InterestingPojo
195 	static class CustomPojo {
196 
197 		@InterestingNeed TestBean testBean;
198 
199 		@InterestingNeedWithRequiredOverride(required=false) NestedTestBean nestedTestBean;
200 	}
201 
202 	@Bean @Lazy @Qualifier("interesting")
203 	@Retention(RetentionPolicy.RUNTIME)
204 	public @interface InterestingBean {
205 	}
206 
207 	@Bean @Lazy @Qualifier("interesting")
208 	@Retention(RetentionPolicy.RUNTIME)
209 	public @interface InterestingBeanWithName {
210 
211 		String name();
212 	}
213 
214 	@Autowired @Qualifier("interesting")
215 	@Retention(RetentionPolicy.RUNTIME)
216 	public @interface InterestingNeed {
217 	}
218 
219 	@Autowired @Qualifier("interesting")
220 	@Retention(RetentionPolicy.RUNTIME)
221 	public @interface InterestingNeedWithRequiredOverride {
222 
223 		boolean required();
224 	}
225 
226 	@Component @Lazy
227 	@Retention(RetentionPolicy.RUNTIME)
228 	public @interface InterestingPojo {
229 	}
230 
231 }