Skip to content

Commit ffa431d

Browse files
committed
Merge branch '6.0.x'
2 parents a91effc + c3c5eaf commit ffa431d

File tree

5 files changed

+79
-14
lines changed

5 files changed

+79
-14
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,8 @@ public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registe
286286
String beanName = registeredBean.getBeanName();
287287
RootBeanDefinition beanDefinition = registeredBean.getMergedBeanDefinition();
288288
InjectionMetadata metadata = findInjectionMetadata(beanName, beanClass, beanDefinition);
289-
Collection<AutowiredElement> autowiredElements = getAutowiredElements(metadata);
289+
Collection<AutowiredElement> autowiredElements = getAutowiredElements(metadata,
290+
registeredBean.getMergedBeanDefinition().getPropertyValues());
290291
if (!ObjectUtils.isEmpty(autowiredElements)) {
291292
return new AotContribution(beanClass, autowiredElements, getAutowireCandidateResolver());
292293
}
@@ -295,8 +296,8 @@ public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registe
295296

296297

297298
@SuppressWarnings({ "rawtypes", "unchecked" })
298-
private Collection<AutowiredElement> getAutowiredElements(InjectionMetadata metadata) {
299-
return (Collection) metadata.getInjectedElements();
299+
private Collection<AutowiredElement> getAutowiredElements(InjectionMetadata metadata, PropertyValues propertyValues) {
300+
return (Collection) metadata.getInjectedElements(propertyValues);
300301
}
301302

302303
@Nullable
@@ -752,7 +753,7 @@ public AutowiredMethodElement(Method method, boolean required, @Nullable Propert
752753

753754
@Override
754755
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
755-
if (checkPropertySkipping(pvs)) {
756+
if (!shouldInject(pvs)) {
756757
return;
757758
}
758759
Method method = (Method) this.member;

spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,19 @@ public Collection<InjectedElement> getInjectedElements() {
9797
return Collections.unmodifiableCollection(this.injectedElements);
9898
}
9999

100+
/**
101+
* Return the {@link InjectedElement elements} to inject based on the
102+
* specified {@link PropertyValues}. If a property is already defined
103+
* for an {@link InjectedElement}, it is excluded.
104+
* @param pvs the property values to consider
105+
* @return the elements to inject
106+
* @since 6.0.10
107+
*/
108+
public Collection<InjectedElement> getInjectedElements(@Nullable PropertyValues pvs) {
109+
return this.injectedElements.stream()
110+
.filter(candidate -> candidate.shouldInject(pvs)).toList();
111+
}
112+
100113
/**
101114
* Determine whether this metadata instance needs to be refreshed.
102115
* @param clazz the current target class
@@ -230,21 +243,28 @@ protected final void checkResourceType(Class<?> resourceType) {
230243
}
231244
}
232245

246+
protected boolean shouldInject(@Nullable PropertyValues pvs) {
247+
if (this.isField) {
248+
return true;
249+
}
250+
return !checkPropertySkipping(pvs);
251+
}
252+
233253
/**
234254
* Either this or {@link #getResourceToInject} needs to be overridden.
235255
*/
236256
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
237257
throws Throwable {
238258

259+
if (!shouldInject(pvs)) {
260+
return;
261+
}
239262
if (this.isField) {
240263
Field field = (Field) this.member;
241264
ReflectionUtils.makeAccessible(field);
242265
field.set(target, getResourceToInject(target, requestingBeanName));
243266
}
244267
else {
245-
if (checkPropertySkipping(pvs)) {
246-
return;
247-
}
248268
try {
249269
Method method = (Method) this.member;
250270
ReflectionUtils.makeAccessible(method);

spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanRegistrationAotContributionTests.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -65,11 +65,15 @@ class AutowiredAnnotationBeanRegistrationAotContributionTests {
6565

6666
private final DefaultListableBeanFactory beanFactory;
6767

68+
private final AutowiredAnnotationBeanPostProcessor beanPostProcessor;
69+
6870

6971
AutowiredAnnotationBeanRegistrationAotContributionTests() {
7072
this.generationContext = new TestGenerationContext();
7173
this.beanRegistrationCode = new MockBeanRegistrationCode(this.generationContext);
7274
this.beanFactory = new DefaultListableBeanFactory();
75+
this.beanPostProcessor = new AutowiredAnnotationBeanPostProcessor();
76+
this.beanPostProcessor.setBeanFactory(this.beanFactory);
7377
}
7478

7579

@@ -185,10 +189,19 @@ void contributeWhenPackagePrivateMethodInjectionOnParentClassInjectsUsingReflect
185189
});
186190
}
187191

192+
@Test
193+
void contributeWhenMethodInjectionHasMatchingPropertyValue() {
194+
RootBeanDefinition beanDefinition = new RootBeanDefinition(InjectionBean.class);
195+
beanDefinition.getPropertyValues().addPropertyValue("counter", 42);
196+
this.beanFactory.registerBeanDefinition("test", beanDefinition);
197+
BeanRegistrationAotContribution contribution = this.beanPostProcessor
198+
.processAheadOfTime(RegisteredBean.of(this.beanFactory, "test"));
199+
assertThat(contribution).isNull();
200+
}
201+
188202
private RegisteredBean getAndApplyContribution(Class<?> beanClass) {
189203
RegisteredBean registeredBean = registerBean(beanClass);
190-
BeanRegistrationAotContribution contribution = new AutowiredAnnotationBeanPostProcessor()
191-
.processAheadOfTime(registeredBean);
204+
BeanRegistrationAotContribution contribution = this.beanPostProcessor.processAheadOfTime(registeredBean);
192205
assertThat(contribution).isNotNull();
193206
contribution.applyTo(this.generationContext, this.beanRegistrationCode);
194207
return registeredBean;
@@ -229,4 +242,15 @@ private void compile(RegisteredBean registeredBean,
229242
result.accept(compiled.getInstance(BiFunction.class), compiled));
230243
}
231244

245+
static class InjectionBean {
246+
247+
private Integer counter;
248+
249+
@Autowired
250+
public void setCounter(Integer counter) {
251+
this.counter = counter;
252+
}
253+
254+
}
255+
232256
}

spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,8 @@ public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registe
359359
String beanName = registeredBean.getBeanName();
360360
RootBeanDefinition beanDefinition = registeredBean.getMergedBeanDefinition();
361361
InjectionMetadata metadata = findInjectionMetadata(beanDefinition, beanClass, beanName);
362-
Collection<InjectedElement> injectedElements = metadata.getInjectedElements();
362+
Collection<InjectedElement> injectedElements = metadata.getInjectedElements(
363+
registeredBean.getMergedBeanDefinition().getPropertyValues());
363364
if (!CollectionUtils.isEmpty(injectedElements)) {
364365
return new AotContribution(beanClass, injectedElements);
365366
}

spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessorAotContributionTests.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.springframework.core.test.tools.CompileWithForkedClassLoader;
4444
import org.springframework.core.test.tools.Compiled;
4545
import org.springframework.core.test.tools.TestCompiler;
46+
import org.springframework.lang.Nullable;
4647
import org.springframework.util.ReflectionUtils;
4748

4849
import static org.assertj.core.api.Assertions.assertThat;
@@ -67,6 +68,20 @@ void setup() {
6768
this.generationContext = new TestGenerationContext();
6869
}
6970

71+
@Test
72+
void processAheadOfTimeWhenPersistenceUnitOnFieldAndPropertyValueSet() {
73+
RegisteredBean registeredBean = registerBean(DefaultPersistenceUnitField.class);
74+
registeredBean.getMergedBeanDefinition().getPropertyValues().add("emf", "myEntityManagerFactory");
75+
assertThat(processAheadOfTime(registeredBean)).isNotNull(); // Field not handled by property values
76+
}
77+
78+
@Test
79+
void processAheadOfTimeWhenPersistenceUnitOnMethodAndPropertyValueSet() {
80+
RegisteredBean registeredBean = registerBean(DefaultPersistenceUnitMethod.class);
81+
registeredBean.getMergedBeanDefinition().getPropertyValues().add("emf", "myEntityManagerFactory");
82+
assertThat(processAheadOfTime(registeredBean)).isNull();
83+
}
84+
7085
@Test
7186
void processAheadOfTimeWhenPersistenceUnitOnPublicField() {
7287
RegisteredBean registeredBean = registerBean(DefaultPersistenceUnitField.class);
@@ -192,16 +207,20 @@ private RegisteredBean registerBean(Class<?> beanClass) {
192207

193208
private void testCompile(RegisteredBean registeredBean,
194209
BiConsumer<BiConsumer<RegisteredBean, Object>, Compiled> result) {
195-
PersistenceAnnotationBeanPostProcessor postProcessor = new PersistenceAnnotationBeanPostProcessor();
196-
BeanRegistrationAotContribution contribution = postProcessor
197-
.processAheadOfTime(registeredBean);
210+
BeanRegistrationAotContribution contribution = processAheadOfTime(registeredBean);
198211
BeanRegistrationCode beanRegistrationCode = mock();
199212
contribution.applyTo(generationContext, beanRegistrationCode);
200213
generationContext.writeGeneratedContent();
201214
TestCompiler.forSystem().with(generationContext)
202215
.compile(compiled -> result.accept(new Invoker(compiled), compiled));
203216
}
204217

218+
@Nullable
219+
private BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
220+
PersistenceAnnotationBeanPostProcessor postProcessor = new PersistenceAnnotationBeanPostProcessor();
221+
return postProcessor.processAheadOfTime(registeredBean);
222+
}
223+
205224
static class Invoker implements BiConsumer<RegisteredBean, Object> {
206225

207226
private Compiled compiled;

0 commit comments

Comments
 (0)