Skip to content

Commit 6dcaec2

Browse files
committed
Make all @bean methods public
This is a continuation of the changes made in 611f978. It makes some more @bean methods public and adds tests to spring-boot-actuator and spring-boot-autoconfigure to prevent against non-public methods being introduced in the future Closes gh-1571
1 parent 611f978 commit 6dcaec2

File tree

5 files changed

+156
-6
lines changed

5 files changed

+156
-6
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2012-2014 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.boot.actuate;
18+
19+
import org.springframework.boot.test.AbstractConfigurationClassTests;
20+
21+
/**
22+
* Tests for the actuator module's @Configuration classes
23+
* @author Andy Wilkinson
24+
*/
25+
public class ActuatorConfigurationClassTests extends AbstractConfigurationClassTests {
26+
27+
}

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ static class JodaModuleAutoConfiguration {
101101

102102
@Bean
103103
@ConditionalOnMissingBean
104-
JodaModule jacksonJodaModule() {
104+
public JodaModule jacksonJodaModule() {
105105
return new JodaModule();
106106
}
107107

@@ -114,7 +114,7 @@ static class Jsr310ModuleAutoConfiguration {
114114

115115
@Bean
116116
@ConditionalOnMissingBean
117-
JSR310Module jacksonJsr310Module() {
117+
public JSR310Module jacksonJsr310Module() {
118118
return new JSR310Module();
119119
}
120120

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/redis/RedisAutoConfiguration.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ protected static class RedisConnectionConfiguration {
5858

5959
@Bean
6060
@ConditionalOnMissingBean
61-
RedisConnectionFactory redisConnectionFactory() throws UnknownHostException {
61+
public RedisConnectionFactory redisConnectionFactory()
62+
throws UnknownHostException {
6263
JedisConnectionFactory factory = new JedisConnectionFactory();
6364
factory.setHostName(this.properties.getHost());
6465
factory.setPort(this.properties.getPort());
@@ -79,7 +80,8 @@ protected static class RedisPooledConnectionConfiguration {
7980

8081
@Bean
8182
@ConditionalOnMissingBean
82-
RedisConnectionFactory redisConnectionFactory() throws UnknownHostException {
83+
public RedisConnectionFactory redisConnectionFactory()
84+
throws UnknownHostException {
8385
JedisConnectionFactory factory = createJedisConnectionFactory();
8486
factory.setHostName(this.properties.getHost());
8587
factory.setPort(this.properties.getPort());
@@ -124,7 +126,7 @@ protected static class RedisConfiguration {
124126

125127
@Bean
126128
@ConditionalOnMissingBean(name = "redisTemplate")
127-
RedisOperations<Object, Object> redisTemplate(
129+
public RedisOperations<Object, Object> redisTemplate(
128130
RedisConnectionFactory redisConnectionFactory)
129131
throws UnknownHostException {
130132
RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
@@ -134,7 +136,7 @@ RedisOperations<Object, Object> redisTemplate(
134136

135137
@Bean
136138
@ConditionalOnMissingBean(StringRedisTemplate.class)
137-
StringRedisTemplate stringRedisTemplate(
139+
public StringRedisTemplate stringRedisTemplate(
138140
RedisConnectionFactory redisConnectionFactory)
139141
throws UnknownHostException {
140142
StringRedisTemplate template = new StringRedisTemplate();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2012-2014 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.boot.autoconfigure;
18+
19+
import org.springframework.boot.test.AbstractConfigurationClassTests;
20+
21+
/**
22+
* Tests for the autoconfigure module's @Configuration classes
23+
* @author Andy Wilkinson
24+
*/
25+
public class AutoConfigureConfigurationClassTests extends AbstractConfigurationClassTests {
26+
27+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright 2012-2014 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.boot.test;
18+
19+
import java.io.IOException;
20+
import java.util.HashSet;
21+
import java.util.Set;
22+
23+
import org.junit.Test;
24+
import org.springframework.asm.Opcodes;
25+
import org.springframework.beans.DirectFieldAccessor;
26+
import org.springframework.context.annotation.Bean;
27+
import org.springframework.context.annotation.Configuration;
28+
import org.springframework.core.io.Resource;
29+
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
30+
import org.springframework.core.io.support.ResourcePatternResolver;
31+
import org.springframework.core.type.AnnotationMetadata;
32+
import org.springframework.core.type.MethodMetadata;
33+
import org.springframework.core.type.classreading.MetadataReader;
34+
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
35+
36+
import static org.junit.Assert.assertEquals;
37+
38+
/**
39+
* @author Andy Wilkinson
40+
*/
41+
public abstract class AbstractConfigurationClassTests {
42+
43+
private ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
44+
45+
@Test
46+
public void allBeanMethodsArePublic() throws IOException, ClassNotFoundException {
47+
Set<String> nonPublicBeanMethods = new HashSet<String>();
48+
for (AnnotationMetadata configurationClass : findConfigurationClasses()) {
49+
Set<MethodMetadata> beanMethods = configurationClass
50+
.getAnnotatedMethods(Bean.class.getName());
51+
for (MethodMetadata methodMetadata : beanMethods) {
52+
if (!isPublic(methodMetadata)) {
53+
nonPublicBeanMethods.add(methodMetadata.getDeclaringClassName() + "."
54+
+ methodMetadata.getMethodName());
55+
}
56+
}
57+
}
58+
59+
assertEquals("Found non-public @Bean methods: " + nonPublicBeanMethods, 0,
60+
nonPublicBeanMethods.size());
61+
}
62+
63+
private Set<AnnotationMetadata> findConfigurationClasses() throws IOException {
64+
Set<AnnotationMetadata> configurationClasses = new HashSet<AnnotationMetadata>();
65+
Resource[] resources = this.resolver.getResources("classpath*:"
66+
+ getClass().getPackage().getName().replace(".", "/") + "/**/*.class");
67+
68+
for (Resource resource : resources) {
69+
if (!isTestClass(resource)) {
70+
MetadataReader metadataReader = new SimpleMetadataReaderFactory()
71+
.getMetadataReader(resource);
72+
AnnotationMetadata annotationMetadata = metadataReader
73+
.getAnnotationMetadata();
74+
if (annotationMetadata.getAnnotationTypes().contains(
75+
Configuration.class.getName())) {
76+
configurationClasses.add(annotationMetadata);
77+
}
78+
}
79+
}
80+
return configurationClasses;
81+
}
82+
83+
private boolean isTestClass(Resource resource) throws IOException {
84+
return resource.getFile().getAbsolutePath().contains("target/test-classes");
85+
}
86+
87+
private boolean isPublic(MethodMetadata methodMetadata) {
88+
int access = (Integer) new DirectFieldAccessor(methodMetadata)
89+
.getPropertyValue("access");
90+
91+
return (access & Opcodes.ACC_PUBLIC) != 0;
92+
}
93+
94+
}

0 commit comments

Comments
 (0)