13 changed files with 307 additions and 18 deletions
@ -0,0 +1,85 @@
@@ -0,0 +1,85 @@
|
||||
/* |
||||
* Copyright 2002-2023 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.test.context.aot; |
||||
|
||||
import org.springframework.aot.generate.ClassNameGenerator; |
||||
import org.springframework.aot.generate.DefaultGenerationContext; |
||||
import org.springframework.aot.generate.GeneratedClasses; |
||||
import org.springframework.aot.generate.GeneratedFiles; |
||||
import org.springframework.aot.hint.RuntimeHints; |
||||
|
||||
/** |
||||
* Extension of {@link DefaultGenerationContext} with a custom implementation of |
||||
* {@link #withName(String)} that is specific to the <em>Spring TestContext Framework</em>. |
||||
* |
||||
* @author Sam Brannen |
||||
* @since 6.0.12 |
||||
*/ |
||||
class TestContextGenerationContext extends DefaultGenerationContext { |
||||
|
||||
private final String featureName; |
||||
|
||||
|
||||
/** |
||||
* Create a new {@link TestContextGenerationContext} instance backed by the |
||||
* specified {@link ClassNameGenerator}, {@link GeneratedFiles}, and |
||||
* {@link RuntimeHints}. |
||||
* @param classNameGenerator the naming convention to use for generated class names |
||||
* @param generatedFiles the generated files |
||||
* @param runtimeHints the runtime hints |
||||
*/ |
||||
TestContextGenerationContext(ClassNameGenerator classNameGenerator, GeneratedFiles generatedFiles, |
||||
RuntimeHints runtimeHints) { |
||||
super(classNameGenerator, generatedFiles, runtimeHints); |
||||
this.featureName = null; |
||||
} |
||||
|
||||
/** |
||||
* Create a new {@link TestContextGenerationContext} instance backed by the |
||||
* specified {@link GeneratedClasses}, {@link GeneratedFiles}, and |
||||
* {@link RuntimeHints}. |
||||
* @param generatedClasses the generated classes |
||||
* @param generatedFiles the generated files |
||||
* @param runtimeHints the runtime hints |
||||
*/ |
||||
private TestContextGenerationContext(GeneratedClasses generatedClasses, GeneratedFiles generatedFiles, |
||||
RuntimeHints runtimeHints, String featureName) { |
||||
super(generatedClasses, generatedFiles, runtimeHints); |
||||
this.featureName = featureName; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Create a new {@link TestContextGenerationContext} instance using the specified |
||||
* feature name to qualify generated assets for a dedicated round of code generation. |
||||
* <p>If <em>this</em> {@code TestContextGenerationContext} has a configured feature |
||||
* name, the supplied feature name will be appended to the existing feature name |
||||
* in order to avoid naming collisions. |
||||
* @param featureName the feature name to use |
||||
* @return a specialized {@link TestContextGenerationContext} for the specified |
||||
* feature name |
||||
*/ |
||||
@Override |
||||
public TestContextGenerationContext withName(String featureName) { |
||||
if (this.featureName != null) { |
||||
featureName = this.featureName + featureName; |
||||
} |
||||
GeneratedClasses generatedClasses = getGeneratedClasses().withFeatureNamePrefix(featureName); |
||||
return new TestContextGenerationContext(generatedClasses, getGeneratedFiles(), getRuntimeHints(), featureName); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
/* |
||||
* Copyright 2002-2023 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.test.context.aot.samples.management; |
||||
|
||||
import java.lang.annotation.Documented; |
||||
import java.lang.annotation.ElementType; |
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
import java.lang.annotation.Target; |
||||
|
||||
/** |
||||
* Marker annotation for "managed" beans. |
||||
* |
||||
* @author Sam Brannen |
||||
* @since 6.0.12 |
||||
*/ |
||||
@Documented |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Target(ElementType.METHOD) |
||||
public @interface Managed { |
||||
} |
||||
@ -0,0 +1,83 @@
@@ -0,0 +1,83 @@
|
||||
/* |
||||
* Copyright 2002-2023 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.test.context.aot.samples.management; |
||||
|
||||
import java.lang.reflect.Executable; |
||||
|
||||
import org.springframework.aot.generate.GenerationContext; |
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution; |
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor; |
||||
import org.springframework.beans.factory.aot.BeanRegistrationCode; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.context.aot.ApplicationContextAotGenerator; |
||||
import org.springframework.context.support.GenericApplicationContext; |
||||
import org.springframework.core.annotation.AnnotatedElementUtils; |
||||
|
||||
/** |
||||
* Configuration class that mimics Spring Boot's AOT support for child management |
||||
* contexts in |
||||
* {@code org.springframework.boot.actuate.autoconfigure.web.server.ChildManagementContextInitializer}. |
||||
* |
||||
* <p>See <a href="https://github.com/spring-projects/spring-framework/issues/30861">gh-30861</a>. |
||||
* |
||||
* @author Sam Brannen |
||||
* @since 6.0.12 |
||||
*/ |
||||
@Configuration |
||||
public class ManagementConfiguration { |
||||
|
||||
@Bean |
||||
static BeanRegistrationAotProcessor beanRegistrationAotProcessor() { |
||||
return registeredBean -> { |
||||
Executable factoryMethod = registeredBean.resolveConstructorOrFactoryMethod(); |
||||
// Make AOT contribution for @Managed @Bean methods.
|
||||
if (AnnotatedElementUtils.hasAnnotation(factoryMethod, Managed.class)) { |
||||
return new AotContribution(createManagementContext()); |
||||
} |
||||
return null; |
||||
}; |
||||
} |
||||
|
||||
private static GenericApplicationContext createManagementContext() { |
||||
GenericApplicationContext managementContext = new GenericApplicationContext(); |
||||
managementContext.registerBean(ManagementMessageService.class); |
||||
return managementContext; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Mimics Spring Boot's AOT support for child management contexts in |
||||
* {@code org.springframework.boot.actuate.autoconfigure.web.server.ChildManagementContextInitializer.AotContribution}. |
||||
*/ |
||||
private static class AotContribution implements BeanRegistrationAotContribution { |
||||
|
||||
private final GenericApplicationContext managementContext; |
||||
|
||||
AotContribution(GenericApplicationContext managementContext) { |
||||
this.managementContext = managementContext; |
||||
} |
||||
|
||||
@Override |
||||
public void applyTo(GenerationContext generationContext, BeanRegistrationCode beanRegistrationCode) { |
||||
GenerationContext managementGenerationContext = generationContext.withName("Management"); |
||||
new ApplicationContextAotGenerator().processAheadOfTime(this.managementContext, managementGenerationContext); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
/* |
||||
* Copyright 2002-2023 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.test.context.aot.samples.management; |
||||
|
||||
import org.springframework.test.context.aot.samples.common.MessageService; |
||||
|
||||
/** |
||||
* {@link MessageService} implemented in a different package. |
||||
* |
||||
* <p>See <a href="https://github.com/spring-projects/spring-framework/issues/30861">gh-30861</a>. |
||||
* |
||||
* @author Sam Brannen |
||||
* @since 6.0.12 |
||||
*/ |
||||
class ManagementMessageService implements MessageService { |
||||
|
||||
@Override |
||||
public String generateMessage() { |
||||
return "Hello, Management!"; |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue