Tweak annotation config concepts

This commit is contained in:
Janne Valkealahti
2015-02-17 09:31:14 +00:00
parent e8b5b3d86a
commit a98e50247d
11 changed files with 368 additions and 34 deletions

View File

@@ -58,14 +58,24 @@ public abstract class AbstractImportingAnnotationConfiguration<B extends Annotat
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
Class<?> annotationType = getAnnotation();
AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(
annotationType.getName(), false));
String[] names = attributes.getStringArray("name");
List<Class<? extends Annotation>> annotationTypes = getAnnotations();
Class<? extends Annotation> namedAnnotation = null;
String[] names = null;
if (annotationTypes != null) {
for (Class<? extends Annotation> annotationType : annotationTypes) {
AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(
annotationType.getName(), false));
if (attributes != null && attributes.containsKey("name")) {
names = attributes.getStringArray("name");
namedAnnotation = annotationType;
break;
}
}
}
BeanDefinition beanDefinition;
try {
beanDefinition = buildBeanDefinition(importingClassMetadata);
beanDefinition = buildBeanDefinition(importingClassMetadata, namedAnnotation);
} catch (Exception e) {
throw new RuntimeException("Error with onConfigurers", e);
}
@@ -98,17 +108,20 @@ public abstract class AbstractImportingAnnotationConfiguration<B extends Annotat
/**
* Called to get a bean definition to register.
*
* @param importingClassMetadata annotation metadata of the importing class
* @param namedAnnotation found annotations for bean names
* @return the bean definition to register
* @throws Exception if error occurred
*/
protected abstract BeanDefinition buildBeanDefinition(AnnotationMetadata importingClassMetadata) throws Exception;
protected abstract BeanDefinition buildBeanDefinition(AnnotationMetadata importingClassMetadata,
Class<? extends Annotation> namedAnnotation) throws Exception;
/**
* Gets the annotation specific for this configurer.
* Gets the annotations specific for this configurer.
*
* @return the annotation
* @return the annotations
*/
protected abstract Class<? extends Annotation> getAnnotation();
protected abstract List<Class<? extends Annotation>> getAnnotations();
/**
* Gets the bean factory.

View File

@@ -16,12 +16,12 @@
package org.springframework.statemachine.config.configuration;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.config.EnableStateMachine;
@@ -32,6 +32,7 @@ import org.springframework.statemachine.config.builders.StateMachineStates;
import org.springframework.statemachine.config.builders.StateMachineTransitions;
import org.springframework.statemachine.config.common.annotation.AbstractImportingAnnotationConfiguration;
import org.springframework.statemachine.config.common.annotation.AnnotationConfigurer;
import org.springframework.util.ClassUtils;
@Configuration
public class StateMachineConfiguration<S extends Enum<S>, E extends Enum<E>> extends
@@ -40,44 +41,39 @@ public class StateMachineConfiguration<S extends Enum<S>, E extends Enum<E>> ext
private final StateMachineConfigBuilder<S, E> builder = new StateMachineConfigBuilder<S, E>();
@Override
protected BeanDefinition buildBeanDefinition(AnnotationMetadata importingClassMetadata) throws Exception {
Class<?> annotationType = getAnnotation();
AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(
annotationType.getName(), false));
String[] names = attributes.getStringArray("name");
protected BeanDefinition buildBeanDefinition(AnnotationMetadata importingClassMetadata,
Class<? extends Annotation> namedAnnotation) throws Exception {
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
.rootBeanDefinition(StateMachineDelegatingFactoryBean2.class);
beanDefinitionBuilder.addConstructorArgValue(builder);
beanDefinitionBuilder.addConstructorArgValue(StateMachine.class);
beanDefinitionBuilder.addConstructorArgValue(names);
beanDefinitionBuilder.addConstructorArgValue(importingClassMetadata.getClassName());
return beanDefinitionBuilder.getBeanDefinition();
}
@Override
protected Class<? extends Annotation> getAnnotation() {
return EnableStateMachine.class;
protected List<Class<? extends Annotation>> getAnnotations() {
List<Class<? extends Annotation>> types = new ArrayList<Class<? extends Annotation>>();
types.add(EnableStateMachine.class);
return types;
}
private static class StateMachineDelegatingFactoryBean2<S extends Enum<S>, E extends Enum<E>>
extends BeanDelegatingFactoryBean<StateMachine<S, E>,StateMachineConfigBuilder<S, E>,StateMachineConfig<S, E>> {
private final String[] beanNames;
private String clazzName;
public StateMachineDelegatingFactoryBean2(StateMachineConfigBuilder<S, E> builder, Class<StateMachine<S, E>> clazz, String[] beanNames) {
public StateMachineDelegatingFactoryBean2(StateMachineConfigBuilder<S, E> builder, Class<StateMachine<S, E>> clazz,
String clazzName) {
super(builder, clazz);
this.beanNames = beanNames;
this.clazzName = clazzName;
}
@Override
public void afterPropertiesSet() throws Exception {
for (AnnotationConfigurer<StateMachineConfig<S, E>, StateMachineConfigBuilder<S, E>> configurer : getConfigurers()) {
Class<?> clazz = configurer.getClass();
EnableStateMachine findAnnotation = AnnotationUtils.findAnnotation(clazz, EnableStateMachine.class);
String[] annonames = findAnnotation.name();
if (beanNames[0].equals(annonames[0])) {
if (ClassUtils.getUserClass(clazz).getName().equals(clazzName)) {
getBuilder().apply(configurer);
}
}

View File

@@ -1,6 +1,7 @@
package org.springframework.statemachine.config.configuration;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.BeansException;
@@ -30,16 +31,20 @@ public class StateMachineFactoryConfiguration<S extends Enum<S>, E extends Enum<
private final StateMachineConfigBuilder<S, E> builder = new StateMachineConfigBuilder<S, E>();
@Override
protected BeanDefinition buildBeanDefinition(AnnotationMetadata importingClassMetadata) throws Exception {
protected BeanDefinition buildBeanDefinition(AnnotationMetadata importingClassMetadata,
Class<? extends Annotation> namedAnnotation) throws Exception {
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
.rootBeanDefinition(StateMachineFactoryDelegatingFactoryBean.class);
beanDefinitionBuilder.addConstructorArgValue(builder);
return beanDefinitionBuilder.getBeanDefinition();
}
@Override
protected Class<? extends Annotation> getAnnotation() {
return EnableStateMachineFactory.class;
protected List<Class<? extends Annotation>> getAnnotations() {
List<Class<? extends Annotation>> types = new ArrayList<Class<? extends Annotation>>();
types.add(EnableStateMachineFactory.class);
return types;
}
private static class StateMachineFactoryDelegatingFactoryBean<S extends Enum<S>, E extends Enum<E>> implements

View File

@@ -0,0 +1,59 @@
/*
* Copyright 2015 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.statemachine.config.common.annotation;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.junit.Assert.assertThat;
import java.util.UUID;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.config.common.annotation.importing.EnableImportingTest;
import org.springframework.statemachine.config.common.annotation.importing.ImportingTestConfigBuilder;
import org.springframework.statemachine.config.common.annotation.importing.ImportingTestConfigurerAdapter;
public class ImportingBeanDefinitionTests {
@Test
public void testCorrentBeanUsed() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
Object beanBuilt = ctx.getBean("enableImportingTestBean");
Object beanInjected = ctx.getBean("uuid");
assertThat(beanBuilt, sameInstance(beanInjected));
ctx.close();
}
@Configuration
@EnableImportingTest
static class Config extends ImportingTestConfigurerAdapter {
@Override
public void configure(ImportingTestConfigBuilder builder) throws Exception {
builder.setUuid(uuid());
}
@Bean
public UUID uuid() {
return UUID.randomUUID();
}
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2015 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.statemachine.config.common.annotation.importing;
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;
import org.springframework.context.annotation.Import;
import org.springframework.statemachine.config.common.annotation.EnableAnnotationConfiguration;
import org.springframework.statemachine.config.common.annotation.configuration.ObjectPostProcessorConfiguration;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@EnableAnnotationConfiguration
@Import({SimpleImportingConfiguration.class, ObjectPostProcessorConfiguration.class})
public @interface EnableImportingTest {
String[] name() default {"enableImportingTestBean"};
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright 2015 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.statemachine.config.common.annotation.importing;
import java.util.UUID;
public class ImportingTestConfig {
public UUID importingData;
public void setImportingData(UUID importingData) {
this.importingData = importingData;
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2015 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.statemachine.config.common.annotation.importing;
import java.util.UUID;
import org.springframework.statemachine.config.common.annotation.AbstractConfiguredAnnotationBuilder;
public class ImportingTestConfigBuilder extends
AbstractConfiguredAnnotationBuilder<ImportingTestConfig, ImportingTestConfigBuilder, ImportingTestConfigBuilder> {
private UUID uuid;
@Override
protected ImportingTestConfig performBuild() throws Exception {
ImportingTestConfig bean = new ImportingTestConfig();
bean.setImportingData(uuid);
return bean;
}
public void setUuid(UUID uuid) {
this.uuid = uuid;
}
}

View File

@@ -0,0 +1,22 @@
/*
* Copyright 2015 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.statemachine.config.common.annotation.importing;
import org.springframework.statemachine.config.common.annotation.AnnotationConfigurer;
public interface ImportingTestConfigurer extends AnnotationConfigurer<ImportingTestConfig, ImportingTestConfigBuilder> {
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2015 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.statemachine.config.common.annotation.importing;
import org.springframework.statemachine.config.common.annotation.AnnotationBuilder;
public class ImportingTestConfigurerAdapter implements ImportingTestConfigurer {
@Override
public void init(ImportingTestConfigBuilder builder) throws Exception {
}
@Override
public void configure(ImportingTestConfigBuilder builder) throws Exception {
}
@Override
public boolean isAssignable(AnnotationBuilder<ImportingTestConfig> builder) {
return builder instanceof ImportingTestConfigBuilder;
}
}

View File

@@ -0,0 +1,95 @@
/*
* Copyright 2015 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.statemachine.config.common.annotation.importing;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.statemachine.config.common.annotation.AbstractImportingAnnotationConfiguration;
import org.springframework.statemachine.config.common.annotation.AnnotationConfigurer;
@Configuration
public class SimpleImportingConfiguration extends
AbstractImportingAnnotationConfiguration<ImportingTestConfigBuilder, ImportingTestConfig> {
private final ImportingTestConfigBuilder builder = new ImportingTestConfigBuilder();
@Override
protected BeanDefinition buildBeanDefinition(AnnotationMetadata importingClassMetadata,
Class<? extends Annotation> namedAnnotation) throws Exception {
List<Class<? extends Annotation>> annotationTypes = getAnnotations();
String[] names = null;
if (annotationTypes != null) {
for (Class<?> annotationType : annotationTypes) {
AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(
annotationType.getName(), false));
if (attributes.containsKey("name")) {
names = attributes.getStringArray("name");
break;
}
}
}
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
.rootBeanDefinition(SimpleUUIDDelegatingFactoryBean.class);
beanDefinitionBuilder.addConstructorArgValue(builder);
beanDefinitionBuilder.addConstructorArgValue(UUID.class);
beanDefinitionBuilder.addConstructorArgValue(names);
return beanDefinitionBuilder.getBeanDefinition();
}
@Override
protected List<Class<? extends Annotation>> getAnnotations() {
List<Class<? extends Annotation>> types = new ArrayList<Class<? extends Annotation>>();
types.add(EnableImportingTest.class);
return types;
}
private static class SimpleUUIDDelegatingFactoryBean extends
BeanDelegatingFactoryBean<UUID, ImportingTestConfigBuilder, ImportingTestConfig> {
private final String[] beanNames;
public SimpleUUIDDelegatingFactoryBean(ImportingTestConfigBuilder builder, Class<UUID> clazz, String[] beanNames) {
super(builder, clazz);
this.beanNames = beanNames;
}
@Override
public void afterPropertiesSet() throws Exception {
for (AnnotationConfigurer<ImportingTestConfig, ImportingTestConfigBuilder> configurer : getConfigurers()) {
Class<?> clazz = configurer.getClass();
EnableImportingTest findAnnotation = AnnotationUtils.findAnnotation(clazz, EnableImportingTest.class);
String[] annonames = findAnnotation.name();
if (beanNames[0].equals(annonames[0])) {
getBuilder().apply(configurer);
}
}
setObject(getBuilder().getOrBuild().importingData);
}
}
}

View File

@@ -16,6 +16,8 @@
package org.springframework.statemachine.config.common.annotation.simple;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@@ -30,7 +32,8 @@ public class SimpleTestConfiguration2 extends AbstractImportingAnnotationConfigu
private final SimpleTestConfigBuilder builder = new SimpleTestConfigBuilder();
@Override
protected BeanDefinition buildBeanDefinition(AnnotationMetadata importingClassMetadata) throws Exception {
protected BeanDefinition buildBeanDefinition(AnnotationMetadata importingClassMetadata,
Class<? extends Annotation> namedAnnotation) throws Exception {
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
.rootBeanDefinition(SimpleTestConfigDelegatingFactoryBean.class);
beanDefinitionBuilder.addConstructorArgValue(builder);
@@ -38,8 +41,10 @@ public class SimpleTestConfiguration2 extends AbstractImportingAnnotationConfigu
}
@Override
protected Class<? extends Annotation> getAnnotation() {
return EnableSimpleTest2.class;
protected List<Class<? extends Annotation>> getAnnotations() {
List<Class<? extends Annotation>> types = new ArrayList<Class<? extends Annotation>>();
types.add(EnableSimpleTest2.class);
return types;
}
private static class SimpleTestConfigDelegatingFactoryBean extends BeanDelegatingFactoryBean<SimpleTestConfig, SimpleTestConfigBuilder, SimpleTestConfig> {