RequiredAnnotationBeanPostProcessor skips factory-bean definitions
Also moving the associated unit tests to the correct package beans.factory.annotation Issue: SPR-10458
This commit is contained in:
@@ -30,6 +30,7 @@ import org.springframework.beans.PropertyValues;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
|
||||
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
|
||||
@@ -165,6 +166,8 @@ public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanP
|
||||
* required property check as performed by this post-processor.
|
||||
* <p>The default implementations check for the presence of the
|
||||
* {@link #SKIP_REQUIRED_CHECK_ATTRIBUTE} attribute in the bean definition, if any.
|
||||
* It also suggests skipping in case of a bean definition with a "factory-bean"
|
||||
* reference set, assuming that instance-based factories pre-populate the bean.
|
||||
* @param beanFactory the BeanFactory to check against
|
||||
* @param beanName the name of the bean to check against
|
||||
* @return {@code true} to skip the bean; {@code false} to process it
|
||||
@@ -173,7 +176,11 @@ public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanP
|
||||
if (beanFactory == null || !beanFactory.containsBeanDefinition(beanName)) {
|
||||
return false;
|
||||
}
|
||||
Object value = beanFactory.getBeanDefinition(beanName).getAttribute(SKIP_REQUIRED_CHECK_ATTRIBUTE);
|
||||
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
|
||||
if (beanDefinition.getFactoryBeanName() != null) {
|
||||
return true;
|
||||
}
|
||||
Object value = beanDefinition.getAttribute(SKIP_REQUIRED_CHECK_ATTRIBUTE);
|
||||
return (value != null && (Boolean.TRUE.equals(value) || Boolean.valueOf(value.toString())));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,195 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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
|
||||
*
|
||||
* http://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.beans.annotation;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
import org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @author Chris Beams
|
||||
* @since 2.0
|
||||
*/
|
||||
public final class RequiredAnnotationBeanPostProcessorTests {
|
||||
|
||||
@Test
|
||||
public void testWithRequiredPropertyOmitted() {
|
||||
try {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
BeanDefinition beanDef = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(RequiredTestBean.class)
|
||||
.addPropertyValue("name", "Rob Harrop")
|
||||
.addPropertyValue("favouriteColour", "Blue")
|
||||
.addPropertyValue("jobTitle", "Grand Poobah")
|
||||
.getBeanDefinition();
|
||||
factory.registerBeanDefinition("testBean", beanDef);
|
||||
factory.addBeanPostProcessor(new RequiredAnnotationBeanPostProcessor());
|
||||
factory.preInstantiateSingletons();
|
||||
fail("Should have thrown BeanCreationException");
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
String message = ex.getCause().getMessage();
|
||||
assertTrue(message.indexOf("Property") > -1);
|
||||
assertTrue(message.indexOf("age") > -1);
|
||||
assertTrue(message.indexOf("testBean") > -1);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithThreeRequiredPropertiesOmitted() {
|
||||
try {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
BeanDefinition beanDef = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(RequiredTestBean.class)
|
||||
.addPropertyValue("name", "Rob Harrop")
|
||||
.getBeanDefinition();
|
||||
factory.registerBeanDefinition("testBean", beanDef);
|
||||
factory.addBeanPostProcessor(new RequiredAnnotationBeanPostProcessor());
|
||||
factory.preInstantiateSingletons();
|
||||
fail("Should have thrown BeanCreationException");
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
String message = ex.getCause().getMessage();
|
||||
assertTrue(message.indexOf("Properties") > -1);
|
||||
assertTrue(message.indexOf("age") > -1);
|
||||
assertTrue(message.indexOf("favouriteColour") > -1);
|
||||
assertTrue(message.indexOf("jobTitle") > -1);
|
||||
assertTrue(message.indexOf("testBean") > -1);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithOnlyRequiredPropertiesSpecified() {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
BeanDefinition beanDef = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(RequiredTestBean.class)
|
||||
.addPropertyValue("age", "24")
|
||||
.addPropertyValue("favouriteColour", "Blue")
|
||||
.addPropertyValue("jobTitle", "Grand Poobah")
|
||||
.getBeanDefinition();
|
||||
factory.registerBeanDefinition("testBean", beanDef);
|
||||
factory.addBeanPostProcessor(new RequiredAnnotationBeanPostProcessor());
|
||||
factory.preInstantiateSingletons();
|
||||
RequiredTestBean bean = (RequiredTestBean) factory.getBean("testBean");
|
||||
assertEquals(24, bean.getAge());
|
||||
assertEquals("Blue", bean.getFavouriteColour());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithCustomAnnotation() {
|
||||
try {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
BeanDefinition beanDef = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(RequiredTestBean.class)
|
||||
.getBeanDefinition();
|
||||
factory.registerBeanDefinition("testBean", beanDef);
|
||||
RequiredAnnotationBeanPostProcessor rabpp = new RequiredAnnotationBeanPostProcessor();
|
||||
rabpp.setRequiredAnnotationType(MyRequired.class);
|
||||
factory.addBeanPostProcessor(rabpp);
|
||||
factory.preInstantiateSingletons();
|
||||
fail("Should have thrown BeanCreationException");
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
String message = ex.getCause().getMessage();
|
||||
assertTrue(message.indexOf("Property") > -1);
|
||||
assertTrue(message.indexOf("name") > -1);
|
||||
assertTrue(message.indexOf("testBean") > -1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@interface MyRequired {
|
||||
}
|
||||
|
||||
|
||||
class RequiredTestBean implements BeanNameAware, BeanFactoryAware {
|
||||
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
|
||||
private String favouriteColour;
|
||||
|
||||
private String jobTitle;
|
||||
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@MyRequired
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getFavouriteColour() {
|
||||
return favouriteColour;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setFavouriteColour(String favouriteColour) {
|
||||
this.favouriteColour = favouriteColour;
|
||||
}
|
||||
|
||||
public String getJobTitle() {
|
||||
return jobTitle;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setJobTitle(String jobTitle) {
|
||||
this.jobTitle = jobTitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Required
|
||||
public void setBeanName(String name) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Required
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.annotation;
|
||||
package org.springframework.beans.factory.annotation;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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
|
||||
*
|
||||
* http://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.beans.factory.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @author Chris Beams
|
||||
* @since 2.0
|
||||
*/
|
||||
public final class RequiredAnnotationBeanPostProcessorTests {
|
||||
|
||||
@Test
|
||||
public void testWithRequiredPropertyOmitted() {
|
||||
try {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
BeanDefinition beanDef = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(RequiredTestBean.class)
|
||||
.addPropertyValue("name", "Rob Harrop")
|
||||
.addPropertyValue("favouriteColour", "Blue")
|
||||
.addPropertyValue("jobTitle", "Grand Poobah")
|
||||
.getBeanDefinition();
|
||||
factory.registerBeanDefinition("testBean", beanDef);
|
||||
factory.addBeanPostProcessor(new RequiredAnnotationBeanPostProcessor());
|
||||
factory.preInstantiateSingletons();
|
||||
fail("Should have thrown BeanCreationException");
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
String message = ex.getCause().getMessage();
|
||||
assertTrue(message.contains("Property"));
|
||||
assertTrue(message.contains("age"));
|
||||
assertTrue(message.contains("testBean"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithThreeRequiredPropertiesOmitted() {
|
||||
try {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
BeanDefinition beanDef = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(RequiredTestBean.class)
|
||||
.addPropertyValue("name", "Rob Harrop")
|
||||
.getBeanDefinition();
|
||||
factory.registerBeanDefinition("testBean", beanDef);
|
||||
factory.addBeanPostProcessor(new RequiredAnnotationBeanPostProcessor());
|
||||
factory.preInstantiateSingletons();
|
||||
fail("Should have thrown BeanCreationException");
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
String message = ex.getCause().getMessage();
|
||||
assertTrue(message.contains("Properties"));
|
||||
assertTrue(message.contains("age"));
|
||||
assertTrue(message.contains("favouriteColour"));
|
||||
assertTrue(message.contains("jobTitle"));
|
||||
assertTrue(message.contains("testBean"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithAllRequiredPropertiesSpecified() {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
BeanDefinition beanDef = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(RequiredTestBean.class)
|
||||
.addPropertyValue("age", "24")
|
||||
.addPropertyValue("favouriteColour", "Blue")
|
||||
.addPropertyValue("jobTitle", "Grand Poobah")
|
||||
.getBeanDefinition();
|
||||
factory.registerBeanDefinition("testBean", beanDef);
|
||||
factory.addBeanPostProcessor(new RequiredAnnotationBeanPostProcessor());
|
||||
factory.preInstantiateSingletons();
|
||||
RequiredTestBean bean = (RequiredTestBean) factory.getBean("testBean");
|
||||
assertEquals(24, bean.getAge());
|
||||
assertEquals("Blue", bean.getFavouriteColour());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithCustomAnnotation() {
|
||||
try {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
BeanDefinition beanDef = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(RequiredTestBean.class)
|
||||
.getBeanDefinition();
|
||||
factory.registerBeanDefinition("testBean", beanDef);
|
||||
RequiredAnnotationBeanPostProcessor rabpp = new RequiredAnnotationBeanPostProcessor();
|
||||
rabpp.setRequiredAnnotationType(MyRequired.class);
|
||||
factory.addBeanPostProcessor(rabpp);
|
||||
factory.preInstantiateSingletons();
|
||||
fail("Should have thrown BeanCreationException");
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
String message = ex.getCause().getMessage();
|
||||
assertTrue(message.contains("Property"));
|
||||
assertTrue(message.contains("name"));
|
||||
assertTrue(message.contains("testBean"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithStaticFactoryMethod() {
|
||||
try {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
BeanDefinition beanDef = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(RequiredTestBean.class)
|
||||
.setFactoryMethod("create")
|
||||
.addPropertyValue("name", "Rob Harrop")
|
||||
.addPropertyValue("favouriteColour", "Blue")
|
||||
.addPropertyValue("jobTitle", "Grand Poobah")
|
||||
.getBeanDefinition();
|
||||
factory.registerBeanDefinition("testBean", beanDef);
|
||||
factory.addBeanPostProcessor(new RequiredAnnotationBeanPostProcessor());
|
||||
factory.preInstantiateSingletons();
|
||||
fail("Should have thrown BeanCreationException");
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
String message = ex.getCause().getMessage();
|
||||
assertTrue(message.contains("Property"));
|
||||
assertTrue(message.contains("age"));
|
||||
assertTrue(message.contains("testBean"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithStaticFactoryMethodAndRequiredPropertiesSpecified() {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
BeanDefinition beanDef = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(RequiredTestBean.class)
|
||||
.setFactoryMethod("create")
|
||||
.addPropertyValue("age", "24")
|
||||
.addPropertyValue("favouriteColour", "Blue")
|
||||
.addPropertyValue("jobTitle", "Grand Poobah")
|
||||
.getBeanDefinition();
|
||||
factory.registerBeanDefinition("testBean", beanDef);
|
||||
factory.addBeanPostProcessor(new RequiredAnnotationBeanPostProcessor());
|
||||
factory.preInstantiateSingletons();
|
||||
RequiredTestBean bean = (RequiredTestBean) factory.getBean("testBean");
|
||||
assertEquals(24, bean.getAge());
|
||||
assertEquals("Blue", bean.getFavouriteColour());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithFactoryBean() {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition beanDef = new RootBeanDefinition(RequiredTestBean.class);
|
||||
beanDef.setFactoryBeanName("testBeanFactory");
|
||||
beanDef.setFactoryMethodName("create");
|
||||
factory.registerBeanDefinition("testBean", beanDef);
|
||||
factory.registerBeanDefinition("testBeanFactory", new RootBeanDefinition(RequiredTestBeanFactory.class));
|
||||
RequiredAnnotationBeanPostProcessor bpp = new RequiredAnnotationBeanPostProcessor();
|
||||
bpp.setBeanFactory(factory);
|
||||
factory.addBeanPostProcessor(bpp);
|
||||
factory.preInstantiateSingletons();
|
||||
}
|
||||
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface MyRequired {
|
||||
}
|
||||
|
||||
|
||||
public static class RequiredTestBean implements BeanNameAware, BeanFactoryAware {
|
||||
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
|
||||
private String favouriteColour;
|
||||
|
||||
private String jobTitle;
|
||||
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@MyRequired
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getFavouriteColour() {
|
||||
return favouriteColour;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setFavouriteColour(String favouriteColour) {
|
||||
this.favouriteColour = favouriteColour;
|
||||
}
|
||||
|
||||
public String getJobTitle() {
|
||||
return jobTitle;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setJobTitle(String jobTitle) {
|
||||
this.jobTitle = jobTitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Required
|
||||
public void setBeanName(String name) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Required
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
}
|
||||
|
||||
public static RequiredTestBean create() {
|
||||
return new RequiredTestBean();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class RequiredTestBeanFactory {
|
||||
|
||||
public RequiredTestBean create() {
|
||||
return new RequiredTestBean();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user