View Javadoc

1   /*
2    * $Id: ClassReloadingBeanFactory.java 793388 2009-07-12 18:17:55Z musachy $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  package org.apache.struts2.spring;
22  
23  import org.springframework.beans.BeanWrapper;
24  import org.springframework.beans.factory.support.RootBeanDefinition;
25  import org.springframework.beans.factory.support.DefaultListableBeanFactory;
26  import org.springframework.beans.factory.CannotLoadBeanClassException;
27  import org.springframework.util.ObjectUtils;
28  import org.springframework.util.ClassUtils;
29  import org.springframework.core.DecoratingClassLoader;
30  
31  import java.lang.reflect.Constructor;
32  
33  
34  /***
35   *  Same as DefaultListableBeanFactory, but it doesn't use the constructor and class cached in RootBeanDefinition
36   */
37  public class ClassReloadingBeanFactory extends DefaultListableBeanFactory {
38      @Override
39      protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
40          Class beanClass = resolveBeanClass(mbd, beanName);
41  
42          if (mbd.getFactoryMethodName() != null) {
43              return instantiateUsingFactoryMethod(beanName, mbd, args);
44          }
45  
46          //commented to cached constructor is not used
47          /* // Shortcut when re-creating the same bean...
48          if (mbd.resolvedConstructorOrFactoryMethod != null) {
49              if (mbd.constructorArgumentsResolved) {
50                  return autowireConstructor(beanName, mbd, null, args);
51              } else {
52                  return instantiateBean(beanName, mbd);
53              }
54          }*/
55  
56          // Need to determine the constructor...
57          Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
58          if (ctors != null ||
59                  mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
60                  mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
61              return autowireConstructor(beanName, mbd, ctors, args);
62          }
63  
64          // No special handling: simply use no-arg constructor.
65          return instantiateBean(beanName, mbd);
66      }
67  
68      protected Class resolveBeanClass(RootBeanDefinition mbd, String beanName, Class[] typesToMatch) {
69          try {
70               //commented to cached class is not used
71              /* if (mbd.hasBeanClass()) {
72                  return mbd.getBeanClass();
73              }*/
74              if (typesToMatch != null) {
75                  ClassLoader tempClassLoader = getTempClassLoader();
76                  if (tempClassLoader != null) {
77                      if (tempClassLoader instanceof DecoratingClassLoader) {
78                          DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
79                          for (int i = 0; i < typesToMatch.length; i++) {
80                              dcl.excludeClass(typesToMatch[i].getName());
81                          }
82                      }
83                      String className = mbd.getBeanClassName();
84                      return (className != null ? ClassUtils.forName(className, tempClassLoader) : null);
85                  }
86              }
87              return mbd.resolveBeanClass(getBeanClassLoader());
88          }
89          catch (ClassNotFoundException ex) {
90              throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
91          }
92          catch (LinkageError err) {
93              throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
94          }
95      }
96  }