Spring framework support with Google App Engine

2019-05-23 14:46发布

Does Google App Engine support the Spring framework?

3条回答
看我几分像从前
2楼-- · 2019-05-23 15:24

Google has an article Optimizing Spring Framework for App Engine Applications. Below is a summary of the main points, but it would behove you to read the article in full.

Reducing or Avoiding the Use of Component Scanning

Disable component scanning by not using the following configuration element in the Spring XML configuration file:

<!-- Component scanning will significantly slow down application initialization time -->
<context:component-scan base-package=""/>

Instead, explicitly declare your dependencies, such as:

<bean id="myComponentBean" class="org.foo.MyComponent"/>
<bean id="myOtherComponentBean" class="org.bar.MyComponent"/>

Reducing or Avoiding the Use of Relationship Autowiring

Let’s see how the “automatic wiring” of the relationships is enabled. For example, consider the following Spring MVC Controller class with a DAO member,

@Controller
@RequestMapping("/movie")
public class MovieController {
  MovieDaoInterface movieDao;
  public void setMovieDao(MovieDaoInterface movieDao) {
    this.movieDao = movieDao;
  }
}

The Spring IoC uses the following XML configuration to set the member property for MovieController.

<bean class="com.example.controller.MovieController">
    <property name="movieDao" ref="movieDao"></property>
</bean>
<!-- movieDao is defined elsewhere in the container configuration -->
<bean id="movieDao" class="com.example.dao.MovieDao" />

Instead, you enable autowire by using the context:annotation-config element in the spring configuration file and define the bean as shown next:

<context:annotation-config />  <!-- Turn on Autowired -->
<bean class="com.example.controller.MovieController" autowire="byType">
</bean>

Disabling XML Validation in Production

To further reduce the loading time of an application, you can disable XML validation in production by following the steps below:

  1. Create a class that extends XmlWebApplicationContext.
  2. Override the initBeanDefinitionReader method.
  3. Set the XmlBeanDefinitionReader validation mode to VALIDATION_NONE. XML validation is enabled if an App Engine application runs within the App Engine SDK and disabled when it runs in production mode.
import com.google.appengine.api.utils.SystemProperty;

public class Custom XmlWebApplicationContext extends XmlWebApplicationContext {
         protected void init BeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
                   super.init BeanDefinitionReader(beanDefinitionReader);
                   if (SystemProperty.environment.value() == SystemProperty.Environment.Value.Production) {
                     beanDefinitionReader.setValidating(false);
                     beanDefinitionReader.setNamespaceAware(true);
                   }
               }
}
  1. Open the web.xml file.
  2. Create a section.
  3. Add a element whose value is contextClass.
  4. Add a element whose value points to the class that you created before.
<context-param>
    <param-name>contextClass</param-name>
    <param-value>com.example.CustomXmlWebApplicationContext</param-value>
</context-param>

Using Lazy-Initialized Beans

Spring’s ApplicationContext creates and configures all singleton beans as part of the initialization process. This is desirable because if there are configuration errors they are discovered immediately. But this has a negative side effect of increasing the application loading time.

This may not be an issue for long-lived services which only have to start once, but is not desirable for the dynamic environment of App Engine applications.

For beans that are used less frequently, and are not required when the container initializes for the first request, this problem can be mitigated by setting the lazy-init attribute to true.

Avoiding Constructor Injection by Name

Spring 3.0 added support for using the constructor parameter name for value disambiguation. Let’s consider the following sample class as an example:

    public class Movie {
    private String name;
    private String synopsis;

    public Movie(String name, String synopsis) {
        this.name = name;
        this.synopsis = synopsis;
    }
}

The corresponding configuration using injection by name is shown as below:

<bean id="movie" class="example.Movie">
    <constructor-arg name="name" value="ET" />
    <constructor-arg name="synopsis" value="Help ET go home" />
</bean>

To make this work “out of the box”, Spring requires that the code must be compiled with the debug flag enabled (-g for all debugging info, or -g:vars to be precise, for the local variable debug information). This allows Spring to look up the parameter name in the debug information. However, since this information is not cached in the JVM, it must be loaded from disk which causes significant I/O time penalty.

To solve this problem you can use one of the following guidelines:

  1. Use the @ConstructorProperties annotation to explicitly name your constructor arguments as shown next.
public class Movie {
    // Fields omitted
    @ConstructorProperties({"name", "synopsis"})
    public Movie(String name, String synopsis) {
        this.name = name;
        this.synopsis = synopsis;
    }
}
  1. Define the bean without using constructor injection by name:
<bean id="movie" class="example.Movie">
    <constructor-arg index=0 value="ET" />
    <constructor-arg index=1 value="Help ET go home" />
</bean>
查看更多
贪生不怕死
3楼-- · 2019-05-23 15:43

what I heard is, the spring startup time alone makes it unfit for google app engine.

the real problem is, spring is bought by VMWare, for their own cloud strategy. They are in direct competition with google app engine. so don't expect the situation is going to get any better.

查看更多
beautiful°
4楼-- · 2019-05-23 15:49

If by saying "Google Apps" you're in fact talking about "Google App Engine" (as the tag suggests), then, "mostly". See here (I'm pointing to the cached page because the "Will it Play in App Engine" google groups post seems to be just spinning interminably). Quoting:

Edit: per @hleinone's comment below, the "mostly" answer has now become "yes" -- Spring Security 3.x runs "out-of-the-box" on Google App Engine (haven't tried it personally, I'm just trusting the comment in question!). [[end-of-edit]]

Spring MVC
Version: 2.5.6
Status: COMPATIBLE

To see Spring's MVC framework running on App Engine, check out the autoshoppe sample application. If you're using Spring forms (e.g. using the spring-form.tld tag library and subclassing SimpleFormController), you will need to register custom editors for your properties. This is covered in http://groups.google.com/group/google-appengine-java/browse_thread/thread/d93fd7385bf85bf7.

Spring ORM
Version: 2.5.6
Status: COMPATIBLE

To get Spring working with the App Engine-provided JPA interface, follow the instructions at http://objectuser.wordpress.com/2009/05/19/spring-jpa-in-google-app-engine/, which discusses a workaround to the dependency on javax.naming needed for @PersistenceContext. A more complex workaround is available at http://groups.google.com/group/google-appengine-java/browse_thread/thread/187d41712ec1d394.

Spring Security
Version(s): ?
Status: SEMI-COMPATIBLE

To work around a ClassNotFoundException, you can use a re-compiled version of the library which adds a StringInsensitiveComparator class -- the download is provided at http://www.google-app-engine.com/blog/post/Spring-security-fix-for-google-app-engine.aspx. See http://www.dotnetguru2.org/bmarchesson/index.php?p=1100 for tips on how to get Spring Security running with App Engine and GWT (in French). See http://groups.google.com/group/google-appengine-java/browse_thread/thread/964e7f5e42840d9c for discussion on the integration.

查看更多
登录 后发表回答