Browse Source
This commit adds reflection hints on fields for classes compiled by AspectJ. Closes gh-31575pull/27229/merge
Sébastien Deleuze
1 year ago
4 changed files with 145 additions and 2 deletions
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
/* |
||||
* 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.aop.aspectj.annotation; |
||||
|
||||
import org.springframework.aot.generate.GenerationContext; |
||||
import org.springframework.aot.hint.MemberCategory; |
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution; |
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor; |
||||
import org.springframework.beans.factory.aot.BeanRegistrationCode; |
||||
import org.springframework.beans.factory.support.RegisteredBean; |
||||
|
||||
/** |
||||
* An AOT {@link BeanRegistrationAotProcessor} that detects the presence of |
||||
* classes compiled with AspectJ and adds the related required field hints. |
||||
* |
||||
* @author Sebastien Deleuze |
||||
* @since 6.1 |
||||
*/ |
||||
public class AspectJAdvisorBeanRegistrationAotProcessor implements BeanRegistrationAotProcessor { |
||||
|
||||
@Override |
||||
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) { |
||||
Class<?> beanClass = registeredBean.getBeanClass(); |
||||
if (AbstractAspectJAdvisorFactory.compiledByAjc(beanClass)) { |
||||
return new AspectJAdvisorContribution(beanClass); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
private static class AspectJAdvisorContribution implements BeanRegistrationAotContribution { |
||||
|
||||
private final Class<?> beanClass; |
||||
|
||||
public AspectJAdvisorContribution(Class<?> beanClass) { |
||||
this.beanClass = beanClass; |
||||
} |
||||
|
||||
@Override |
||||
public void applyTo(GenerationContext generationContext, BeanRegistrationCode beanRegistrationCode) { |
||||
generationContext.getRuntimeHints().reflection().registerType(this.beanClass, MemberCategory.DECLARED_FIELDS); |
||||
} |
||||
} |
||||
|
||||
} |
@ -1,5 +1,6 @@
@@ -1,5 +1,6 @@
|
||||
org.springframework.beans.factory.aot.BeanRegistrationAotProcessor=\ |
||||
org.springframework.aop.scope.ScopedProxyBeanRegistrationAotProcessor |
||||
org.springframework.aop.scope.ScopedProxyBeanRegistrationAotProcessor,\ |
||||
org.springframework.aop.aspectj.annotation.AspectJAdvisorBeanRegistrationAotProcessor |
||||
|
||||
org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor= \ |
||||
org.springframework.aop.aspectj.annotation.AspectJBeanFactoryInitializationAotProcessor |
||||
|
@ -0,0 +1,84 @@
@@ -0,0 +1,84 @@
|
||||
/* |
||||
* 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.aop.aspectj; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.aop.aspectj.annotation.AspectJAdvisorBeanRegistrationAotProcessor; |
||||
import org.springframework.aot.generate.GenerationContext; |
||||
import org.springframework.aot.hint.MemberCategory; |
||||
import org.springframework.aot.hint.RuntimeHints; |
||||
import org.springframework.aot.test.generate.TestGenerationContext; |
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution; |
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory; |
||||
import org.springframework.beans.factory.support.RegisteredBean; |
||||
import org.springframework.beans.factory.support.RootBeanDefinition; |
||||
import org.springframework.lang.Nullable; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.mockito.Mockito.mock; |
||||
import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.reflection; |
||||
|
||||
/** |
||||
* Tests for {@link AspectJAdvisorBeanRegistrationAotProcessor}. |
||||
* |
||||
* @author Sebastien Deleuze |
||||
*/ |
||||
public class AspectJAdvisorBeanRegistrationAotProcessorTests { |
||||
|
||||
private final GenerationContext generationContext = new TestGenerationContext(); |
||||
|
||||
private final RuntimeHints runtimeHints = this.generationContext.getRuntimeHints(); |
||||
|
||||
@Test |
||||
void shouldProcessesAspectJClass() { |
||||
process(AspectJClass.class); |
||||
assertThat(reflection().onType(AspectJClass.class).withMemberCategory(MemberCategory.DECLARED_FIELDS)) |
||||
.accepts(this.runtimeHints); |
||||
} |
||||
|
||||
@Test |
||||
void shouldSkipRegularClass() { |
||||
process(RegularClass.class); |
||||
assertThat(this.runtimeHints.reflection().typeHints()).isEmpty(); |
||||
} |
||||
|
||||
void process(Class<?> beanClass) { |
||||
BeanRegistrationAotContribution contribution = createContribution(beanClass); |
||||
if (contribution != null) { |
||||
contribution.applyTo(this.generationContext, mock()); |
||||
} |
||||
} |
||||
|
||||
@Nullable |
||||
private static BeanRegistrationAotContribution createContribution(Class<?> beanClass) { |
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); |
||||
beanFactory.registerBeanDefinition(beanClass.getName(), new RootBeanDefinition(beanClass)); |
||||
return new AspectJAdvisorBeanRegistrationAotProcessor() |
||||
.processAheadOfTime(RegisteredBean.of(beanFactory, beanClass.getName())); |
||||
} |
||||
|
||||
|
||||
static class AspectJClass { |
||||
private static java.lang.Throwable ajc$initFailureCause; |
||||
} |
||||
|
||||
static class RegularClass { |
||||
private static java.lang.Throwable initFailureCause; |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue