You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by gp...@apache.org on 2015/10/16 20:43:50 UTC

deltaspike git commit: DELTASPIKE-1003 support for @Produces in partial-beans

Repository: deltaspike
Updated Branches:
  refs/heads/master 737d53063 -> 7988bfc96


DELTASPIKE-1003 support for @Produces in partial-beans


Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/7988bfc9
Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/7988bfc9
Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/7988bfc9

Branch: refs/heads/master
Commit: 7988bfc960d6cdb91fcb998d82081df233dc1546
Parents: 737d530
Author: gpetracek <gp...@apache.org>
Authored: Fri Oct 16 17:38:27 2015 +0200
Committer: gpetracek <gp...@apache.org>
Committed: Fri Oct 16 20:37:15 2015 +0200

----------------------------------------------------------------------
 .../DeltaSpikePartialProducerLifecycle.java     |  52 ++++++++
 .../impl/PartialBeanBindingExtension.java       | 125 ++++++++++++++++++-
 .../PartialBeanWithProducerEarFileTest.java     |  43 +++++++
 .../uc009/PartialBeanWithProducerTest.java      |  53 ++++++++
 .../PartialBeanWithProducerWarFileTest.java     |  48 +++++++
 .../api/partialbean/uc009/TestBaseConfig.java   |  30 +++++
 .../core/api/partialbean/uc009/TestConfig.java  |  32 +++++
 .../api/partialbean/uc009/TestCustomType.java   |  40 ++++++
 .../partialbean/uc009/TestTypeSafeConfig.java   |  35 ++++++
 .../uc009/TestTypeSafeConfigHandler.java        |  54 ++++++++
 .../core/api/partialbean/uc009/TestValue.java   |  33 +++++
 11 files changed, 544 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/deltaspike/blob/7988bfc9/deltaspike/modules/partial-bean/impl/src/main/java/org/apache/deltaspike/partialbean/impl/DeltaSpikePartialProducerLifecycle.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/partial-bean/impl/src/main/java/org/apache/deltaspike/partialbean/impl/DeltaSpikePartialProducerLifecycle.java b/deltaspike/modules/partial-bean/impl/src/main/java/org/apache/deltaspike/partialbean/impl/DeltaSpikePartialProducerLifecycle.java
new file mode 100644
index 0000000..97855c3
--- /dev/null
+++ b/deltaspike/modules/partial-bean/impl/src/main/java/org/apache/deltaspike/partialbean/impl/DeltaSpikePartialProducerLifecycle.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.deltaspike.partialbean.impl;
+
+import org.apache.deltaspike.core.api.provider.BeanProvider;
+import org.apache.deltaspike.core.util.ReflectionUtils;
+import org.apache.deltaspike.core.util.metadata.builder.ContextualLifecycle;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import java.lang.reflect.Method;
+
+public class DeltaSpikePartialProducerLifecycle<T> implements ContextualLifecycle<T>
+{
+    private final Class targetPartialBeanClass;
+    private final Method producerMethod;
+
+    public DeltaSpikePartialProducerLifecycle(Class targetPartialBeanClass, Method producerMethod)
+    {
+        this.targetPartialBeanClass = targetPartialBeanClass;
+        this.producerMethod = producerMethod;
+    }
+
+    @Override
+    public T create(Bean<T> bean, CreationalContext<T> creationalContext)
+    {
+        Object partialBean = BeanProvider.getContextualReference(this.targetPartialBeanClass);
+        return (T)ReflectionUtils.invokeMethod(partialBean, this.producerMethod, Object.class, false);
+    }
+
+    @Override
+    public void destroy(Bean<T> bean, T instance, CreationalContext<T> creationalContext)
+    {
+        //we don't need to support disposer-methods for now (because it's just about exposing injectable values)
+    }
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/7988bfc9/deltaspike/modules/partial-bean/impl/src/main/java/org/apache/deltaspike/partialbean/impl/PartialBeanBindingExtension.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/partial-bean/impl/src/main/java/org/apache/deltaspike/partialbean/impl/PartialBeanBindingExtension.java b/deltaspike/modules/partial-bean/impl/src/main/java/org/apache/deltaspike/partialbean/impl/PartialBeanBindingExtension.java
index 916a068..75e66db 100644
--- a/deltaspike/modules/partial-bean/impl/src/main/java/org/apache/deltaspike/partialbean/impl/PartialBeanBindingExtension.java
+++ b/deltaspike/modules/partial-bean/impl/src/main/java/org/apache/deltaspike/partialbean/impl/PartialBeanBindingExtension.java
@@ -18,13 +18,20 @@
  */
 package org.apache.deltaspike.partialbean.impl;
 
+import java.io.Serializable;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
+import javax.enterprise.context.Dependent;
 import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Produces;
 import javax.enterprise.inject.spi.AfterBeanDiscovery;
 import javax.enterprise.inject.spi.AnnotatedType;
 import javax.enterprise.inject.spi.Bean;
@@ -33,7 +40,10 @@ import javax.enterprise.inject.spi.BeforeBeanDiscovery;
 import javax.enterprise.inject.spi.Extension;
 import javax.enterprise.inject.spi.ProcessAnnotatedType;
 
+import org.apache.deltaspike.core.api.literal.DefaultLiteral;
 import org.apache.deltaspike.core.spi.activation.Deactivatable;
+import org.apache.deltaspike.core.util.AnnotationUtils;
+import org.apache.deltaspike.core.util.BeanUtils;
 import org.apache.deltaspike.core.util.ClassDeactivationUtils;
 import org.apache.deltaspike.core.util.bean.BeanBuilder;
 import org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder;
@@ -141,6 +151,14 @@ public class PartialBeanBindingExtension implements Extension, Deactivatable
                     if (partialBean != null)
                     {
                         afterBeanDiscovery.addBean(partialBean);
+
+                        List<Bean> partialProducerBeans =
+                            createPartialProducersDefinedIn(partialBean, afterBeanDiscovery, beanManager);
+
+                        for (Bean partialProducerBean : partialProducerBeans)
+                        {
+                            afterBeanDiscovery.addBean(partialProducerBean);
+                        }
                     }
                 }
             }
@@ -149,7 +167,6 @@ public class PartialBeanBindingExtension implements Extension, Deactivatable
         this.descriptors.clear();
     }
 
-
     protected <T> Bean<T> createPartialBean(Class<T> beanClass, PartialBeanDescriptor descriptor,
             AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager)
     {
@@ -191,4 +208,110 @@ public class PartialBeanBindingExtension implements Extension, Deactivatable
 
         return null;
     }
+
+    /*
+     * logic for partial-producers
+     */
+
+    protected List<Bean> createPartialProducersDefinedIn(
+        Bean partialBean, AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager)
+    {
+        Class currentClass = partialBean.getBeanClass();
+        return createPartialProducersDefinedIn(partialBean, afterBeanDiscovery, beanManager, currentClass);
+    }
+
+    private List<Bean> createPartialProducersDefinedIn(
+        Bean partialBean, AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager, Class currentClass)
+    {
+        List<Bean> result = new ArrayList<Bean>();
+
+        while (currentClass != null && !Object.class.getName().equals(currentClass.getName()))
+        {
+            for (Class interfaceClass : currentClass.getInterfaces())
+            {
+                if (interfaceClass.getName().startsWith("java.") || interfaceClass.getName().startsWith("javax."))
+                {
+                    continue;
+                }
+                result.addAll(
+                    createPartialProducersDefinedIn(partialBean, afterBeanDiscovery, beanManager, interfaceClass));
+            }
+
+            for (Method currentMethod : currentClass.getDeclaredMethods())
+            {
+                if (currentMethod.isAnnotationPresent(Produces.class))
+                {
+                    if (currentMethod.getParameterTypes().length > 0)
+                    {
+                        afterBeanDiscovery.addDefinitionError(
+                            new IllegalStateException(
+                                "Producer-methods in partial-beans currently don't support injection-points. " +
+                                "Please remove the parameters from " +
+                                currentMethod.toString() + " in " + currentClass.getName()));
+                    }
+
+                    DeltaSpikePartialProducerLifecycle lifecycle =
+                        new DeltaSpikePartialProducerLifecycle(partialBean.getBeanClass(), currentMethod);
+
+                    Class<? extends Annotation> scopeClass =
+                        extractScope(currentMethod.getDeclaredAnnotations(), beanManager);
+
+                    Class<?> producerResultType = currentMethod.getReturnType();
+
+                    boolean passivationCapable =
+                        Serializable.class.isAssignableFrom(producerResultType) || producerResultType.isPrimitive();
+
+                    Set<Annotation> qualifiers = extractQualifiers(currentMethod.getDeclaredAnnotations(), beanManager);
+
+                    BeanBuilder<?> beanBuilder = new BeanBuilder(beanManager)
+                            .beanClass(producerResultType)
+                            .types(Object.class, producerResultType)
+                            .qualifiers(qualifiers)
+                            .passivationCapable(passivationCapable)
+                            .scope(scopeClass)
+                            .id(createPartialProducerId(currentClass, currentMethod, qualifiers))
+                            .beanLifecycle(lifecycle);
+
+                    result.add(beanBuilder.create());
+                }
+            }
+
+            currentClass = currentClass.getSuperclass();
+        }
+
+        return result;
+    }
+
+    private Set<Annotation> extractQualifiers(Annotation[] annotations, BeanManager beanManager)
+    {
+        Set<Annotation> result = BeanUtils.getQualifiers(beanManager, annotations);
+
+        if (result.isEmpty())
+        {
+            result.add(new DefaultLiteral());
+        }
+        return result;
+    }
+
+    private Class<? extends Annotation> extractScope(Annotation[] annotations, BeanManager beanManager)
+    {
+        for (Annotation annotation : annotations)
+        {
+            if (beanManager.isScope(annotation.annotationType()))
+            {
+                return annotation.annotationType();
+            }
+        }
+        return Dependent.class;
+    }
+
+    private String createPartialProducerId(Class currentClass, Method currentMethod, Set<Annotation> qualifiers)
+    {
+        int qualifierHashCode = 0;
+        for (Annotation qualifier : qualifiers)
+        {
+            qualifierHashCode += AnnotationUtils.getQualifierHashCode(qualifier);
+        }
+        return "PartialProducer#" + currentClass.getName() + "#" + currentMethod.getName() + "#" + qualifierHashCode;
+    }
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/7988bfc9/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/PartialBeanWithProducerEarFileTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/PartialBeanWithProducerEarFileTest.java b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/PartialBeanWithProducerEarFileTest.java
new file mode 100644
index 0000000..26453af
--- /dev/null
+++ b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/PartialBeanWithProducerEarFileTest.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.deltaspike.test.core.api.partialbean.uc009;
+
+import org.apache.deltaspike.test.category.EnterpriseArchiveProfileCategory;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.EnterpriseArchive;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+
+@RunWith(Arquillian.class)
+@Category(EnterpriseArchiveProfileCategory.class)
+public class PartialBeanWithProducerEarFileTest extends PartialBeanWithProducerTest
+{
+    @Deployment
+    public static EnterpriseArchive deployEar()
+    {
+        //workaround for tomee - the ear-file needs to have the same name as the war-file
+        String simpleName = PartialBeanWithProducerWarFileTest.class.getSimpleName();
+        String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1);
+
+        return ShrinkWrap.create(EnterpriseArchive.class, archiveName + ".ear")
+                .addAsModule(PartialBeanWithProducerWarFileTest.deploy());
+    }
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/7988bfc9/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/PartialBeanWithProducerTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/PartialBeanWithProducerTest.java b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/PartialBeanWithProducerTest.java
new file mode 100644
index 0000000..4e8b4ba
--- /dev/null
+++ b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/PartialBeanWithProducerTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.deltaspike.test.core.api.partialbean.uc009;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.inject.Inject;
+
+public abstract class PartialBeanWithProducerTest
+{
+    @Inject
+    private TestConfig testConfig;
+
+    @Inject
+    @TestValue
+    private String value2;
+
+    @Inject
+    private TestCustomType value4;
+
+    @Test
+    public void testPartialBeanWithProducerManualAccess() throws Exception
+    {
+        Assert.assertEquals(new Integer(1), testConfig.value1());
+        Assert.assertEquals("2", testConfig.value2());
+        Assert.assertEquals(new Integer(3), testConfig.value3());
+        Assert.assertEquals(new Integer(4), testConfig.value4().getTestValue());
+    }
+
+    @Test
+    public void testProducedResultOfPartialBeanWithProducer() throws Exception
+    {
+        Assert.assertEquals("2", value2);
+        Assert.assertEquals(new Integer(4), value4.getTestValue());
+    }
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/7988bfc9/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/PartialBeanWithProducerWarFileTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/PartialBeanWithProducerWarFileTest.java b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/PartialBeanWithProducerWarFileTest.java
new file mode 100644
index 0000000..6cf9887
--- /dev/null
+++ b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/PartialBeanWithProducerWarFileTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.deltaspike.test.core.api.partialbean.uc009;
+
+import org.apache.deltaspike.test.core.api.partialbean.util.ArchiveUtils;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.runner.RunWith;
+
+@RunWith(Arquillian.class)
+public class PartialBeanWithProducerWarFileTest extends PartialBeanWithProducerTest
+{
+    @Deployment
+    public static WebArchive deploy()
+    {
+        String simpleName = PartialBeanWithProducerWarFileTest.class.getSimpleName();
+        String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1);
+
+        JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar")
+                .addPackage(PartialBeanWithProducerWarFileTest.class.getPackage())
+                .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
+
+        return ShrinkWrap.create(WebArchive.class, archiveName + ".war")
+                .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndPartialBeanArchive())
+                .addAsLibraries(testJar)
+                .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
+    }
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/7988bfc9/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestBaseConfig.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestBaseConfig.java b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestBaseConfig.java
new file mode 100644
index 0000000..1bbbcb6
--- /dev/null
+++ b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestBaseConfig.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.deltaspike.test.core.api.partialbean.uc009;
+
+import javax.enterprise.inject.Produces;
+
+public interface TestBaseConfig
+{
+    Integer value1();
+
+    @Produces
+    @TestValue
+    String value2();
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/7988bfc9/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestConfig.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestConfig.java b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestConfig.java
new file mode 100644
index 0000000..2587266
--- /dev/null
+++ b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestConfig.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.deltaspike.test.core.api.partialbean.uc009;
+
+import javax.enterprise.context.SessionScoped;
+import javax.enterprise.inject.Produces;
+
+@TestTypeSafeConfig
+public interface TestConfig extends TestBaseConfig
+{
+    Integer value3();
+
+    @Produces
+    @SessionScoped
+    TestCustomType value4();
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/7988bfc9/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestCustomType.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestCustomType.java b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestCustomType.java
new file mode 100644
index 0000000..4d3ef93
--- /dev/null
+++ b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestCustomType.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.deltaspike.test.core.api.partialbean.uc009;
+
+import javax.enterprise.inject.Typed;
+import java.io.Serializable;
+
+@Typed()
+public class TestCustomType implements Serializable
+{
+    private Integer testValue;
+
+    public static TestCustomType parse(String value)
+    {
+        TestCustomType result = new TestCustomType();
+        result.testValue = Integer.parseInt(value);
+        return result;
+    }
+
+    public Integer getTestValue()
+    {
+        return testValue;
+    }
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/7988bfc9/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestTypeSafeConfig.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestTypeSafeConfig.java b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestTypeSafeConfig.java
new file mode 100644
index 0000000..cf5ea60
--- /dev/null
+++ b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestTypeSafeConfig.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.deltaspike.test.core.api.partialbean.uc009;
+
+import org.apache.deltaspike.partialbean.api.PartialBeanBinding;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@PartialBeanBinding
+
+@Retention(RUNTIME)
+@Target(TYPE)
+public @interface TestTypeSafeConfig
+{
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/7988bfc9/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestTypeSafeConfigHandler.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestTypeSafeConfigHandler.java b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestTypeSafeConfigHandler.java
new file mode 100644
index 0000000..73e0429
--- /dev/null
+++ b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestTypeSafeConfigHandler.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.deltaspike.test.core.api.partialbean.uc009;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+@TestTypeSafeConfig
+@SuppressWarnings("unused")
+public class TestTypeSafeConfigHandler implements InvocationHandler
+{
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+    {
+        String stringValue = getTestValue(method.getName());
+        Object parsedValue = null;
+
+        final Class<?> configType = method.getReturnType();
+        if (configType.equals(Integer.class))
+        {
+            parsedValue = Integer.parseInt(stringValue);
+        }
+        else if (configType.equals(String.class))
+        {
+            parsedValue = stringValue;
+        }
+        else if (configType.equals(TestCustomType.class))
+        {
+            parsedValue = TestCustomType.parse(stringValue);
+        }
+
+        return parsedValue;
+    }
+
+    private String getTestValue(String methodName)
+    {
+        return methodName.replace("value", "");
+    }
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/7988bfc9/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestValue.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestValue.java b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestValue.java
new file mode 100644
index 0000000..c3f4bd6
--- /dev/null
+++ b/deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestValue.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.deltaspike.test.core.api.partialbean.uc009;
+
+import javax.inject.Qualifier;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Target({METHOD, FIELD})
+@Retention(RUNTIME)
+@Qualifier
+public @interface TestValue
+{
+}