001: /*
002: * Copyright 2002-2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.beans.factory.support;
018:
019: import java.lang.reflect.Constructor;
020: import java.lang.reflect.InvocationTargetException;
021: import java.lang.reflect.Method;
022: import java.lang.reflect.Modifier;
023:
024: import org.springframework.beans.BeanInstantiationException;
025: import org.springframework.beans.BeanUtils;
026: import org.springframework.beans.factory.BeanDefinitionStoreException;
027: import org.springframework.beans.factory.BeanFactory;
028: import org.springframework.util.StringUtils;
029:
030: /**
031: * Simple object instantiation strategy for use in a BeanFactory.
032: *
033: * <p>Does not support Method Injection, although it provides hooks for subclasses
034: * to override to add Method Injection support, for example by overriding methods.
035: *
036: * @author Rod Johnson
037: * @author Juergen Hoeller
038: * @since 1.1
039: */
040: public class SimpleInstantiationStrategy implements
041: InstantiationStrategy {
042:
043: public Object instantiate(RootBeanDefinition beanDefinition,
044: String beanName, BeanFactory owner) {
045:
046: // Don't override the class with CGLIB if no overrides.
047: if (beanDefinition.getMethodOverrides().isEmpty()) {
048: Constructor constructorToUse = (Constructor) beanDefinition.resolvedConstructorOrFactoryMethod;
049: if (constructorToUse == null) {
050: Class clazz = beanDefinition.getBeanClass();
051: if (clazz.isInterface()) {
052: throw new BeanInstantiationException(clazz,
053: "Specified class is an interface");
054: }
055: try {
056: constructorToUse = clazz
057: .getDeclaredConstructor((Class[]) null);
058: beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
059: } catch (Exception ex) {
060: throw new BeanInstantiationException(clazz,
061: "No default constructor found", ex);
062: }
063: }
064: return BeanUtils.instantiateClass(constructorToUse, null);
065: } else {
066: // Must generate CGLIB subclass.
067: return instantiateWithMethodInjection(beanDefinition,
068: beanName, owner);
069: }
070: }
071:
072: /**
073: * Subclasses can override this method, which is implemented to throw
074: * UnsupportedOperationException, if they can instantiate an object with
075: * the Method Injection specified in the given RootBeanDefinition.
076: * Instantiation should use a no-arg constructor.
077: */
078: protected Object instantiateWithMethodInjection(
079: RootBeanDefinition beanDefinition, String beanName,
080: BeanFactory owner) {
081:
082: throw new UnsupportedOperationException(
083: "Method Injection not supported in SimpleInstantiationStrategy");
084: }
085:
086: public Object instantiate(RootBeanDefinition beanDefinition,
087: String beanName, BeanFactory owner, Constructor ctor,
088: Object[] args) {
089:
090: if (beanDefinition.getMethodOverrides().isEmpty()) {
091: return BeanUtils.instantiateClass(ctor, args);
092: } else {
093: return instantiateWithMethodInjection(beanDefinition,
094: beanName, owner, ctor, args);
095: }
096: }
097:
098: /**
099: * Subclasses can override this method, which is implemented to throw
100: * UnsupportedOperationException, if they can instantiate an object with
101: * the Method Injection specified in the given RootBeanDefinition.
102: * Instantiation should use the given constructor and parameters.
103: */
104: protected Object instantiateWithMethodInjection(
105: RootBeanDefinition beanDefinition, String beanName,
106: BeanFactory owner, Constructor ctor, Object[] args) {
107:
108: throw new UnsupportedOperationException(
109: "Method Injection not supported in SimpleInstantiationStrategy");
110: }
111:
112: public Object instantiate(RootBeanDefinition beanDefinition,
113: String beanName, BeanFactory owner, Object factoryBean,
114: Method factoryMethod, Object[] args) {
115:
116: try {
117: // It's a static method if the target is null.
118: if (!Modifier.isPublic(factoryMethod.getModifiers())
119: || !Modifier.isPublic(factoryMethod
120: .getDeclaringClass().getModifiers())) {
121: factoryMethod.setAccessible(true);
122: }
123: return factoryMethod.invoke(factoryBean, args);
124: } catch (IllegalArgumentException ex) {
125: throw new BeanDefinitionStoreException(
126: "Illegal arguments to factory method ["
127: + factoryMethod
128: + "]; "
129: + "args: "
130: + StringUtils
131: .arrayToCommaDelimitedString(args));
132: } catch (IllegalAccessException ex) {
133: throw new BeanDefinitionStoreException(
134: "Cannot access factory method [" + factoryMethod
135: + "]; is it public?");
136: } catch (InvocationTargetException ex) {
137: throw new BeanDefinitionStoreException("Factory method ["
138: + factoryMethod + "] threw exception", ex
139: .getTargetException());
140: }
141: }
142:
143: }
|