2015-03-23 24 views
8

Mam skonfigurowaną i działającą aplikację REST opartą na Spring, ale teraz chcę ją przekonwertować na Spring-Boot.Konwertuj istniejącą aplikację Spring na Spring-Boot

Moja aplikacja używa wiosna-data-WZP na szczycie JPA źródła danych z hibernacji oferenta:

@Configuration 
@EnableJpaRepositories("foo.bar.web.repository") 
@EnableTransactionManagement 
public class RepositoryConfig { 

    // properties ommited 

    @Bean 
    public DataSource dataSource() { 
     BasicDataSource dataSource = new BasicDataSource(); 
     dataSource.setDriverClassName(className); 
     dataSource.setUrl(url); 
     dataSource.setUsername(userName); 
     dataSource.setPassword(password); 
     return dataSource; 
    } 

    @Bean 
    public EntityManagerFactory entityManagerFactory() { 
     LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); 
     factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); 
     factory.setPackagesToScan("foo.bar.web.domain"); 
     factory.setDataSource(dataSource()); 
     factory.setJpaPropertyMap(new HashMap<String, Object>() {{ 
      put("hibernate.dialect", dialect); 
      put("hibernate.hbm2ddl.auto", hbm2ddl); 
     }}); 
     factory.afterPropertiesSet(); 
     return factory.getObject(); 
    } 

    @Bean 
    public PlatformTransactionManager transactionManager() { 
     JpaTransactionManager transactionManager = new JpaTransactionManager(); 
     transactionManager.setEntityManagerFactory(entityManagerFactory()); 
     return transactionManager; 
    } 
} 

mego odpoczynku punkty końcowe realizowanego za pomocą SpringMVC o następującej konfiguracji:

@Configuration 
@EnableWebMvc 
@ComponentScan("foo.bar.web.controller") 
public class MvcConfig extends WebMvcConfigurerAdapter { 

    @Override 
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { 
     configurer.enable(); 
    } 

    @Bean 
    public MultipartResolver multipartResolver() { 
     return new CommonsMultipartResolver(); 
    } 
} 

Web Inicjator:

public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { 

    @Override 
    protected Class<?>[] getRootConfigClasses() { 
     return new Class[]{ 
       ApplicationConfig.class, 
       RepositoryConfig.class 
     }; 
    } 

    @Override 
    protected Class<?>[] getServletConfigClasses() { 
     return new Class[]{MvcConfig.class}; 
    } 

    @Override 
    protected String[] getServletMappings() { 
     return new String[]{"/"}; 
    } 
} 

Problem polega na tym, że nie chcę używać Spring-Boo t automatyczna konfiguracja, ponieważ chciałbym ponownie użyć istniejących klas konfiguracji przy minimalnych zmianach, ale nie mogę znaleźć prawidłowego sposobu, aby to zrobić. Próbowałem zaimplementować klasę aplikacji Spring-boot opisaną pod @SrpingBootApplication, ale nie jestem w 100% pewna, że ​​moje klasy konfiguracyjne są używane, ponieważ w tym przypadku otrzymuję java.lang.ClassCastException: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean$$EnhancerBySpringCGLIB$$ba21071f cannot be cast to javax.persistence.EntityManagerFactory.

Próbowałem również wyrzucić @EnableAutoConfiguration adnotacji z klasy aplikacji i dodać fasola TomcatEmbeddedServletContainerFactory do mojego kontekstu ręcznie, ale w tym przypadku wbudowany tomcat nie jest poprawnie skonfigurowany.

Byłoby wspaniale, gdyby ktoś dał mi wskazówkę, jak rozwiązać mój problem. Uważam, że wszystko, co muszę zrobić, to zastąpić mój WebInitilizer konfiguracją Spring-Boot.

+1

Proponuję użyć funkcji automatycznej konfiguracji, ponieważ pozwoli to w zasadzie porzucić większość konfiguracji lub umieścić w 'application.properties'. Najlepszym możliwym do utrzymania kodowaniem nie jest kod. –

+0

Całkowicie zgadzam się z tobą, że automatyczna konfiguracja to dobra funkcja, ale to jest mój projekt edukacyjny i myślę, że ręczna konfiguracja jest bardziej przydatna do zrozumienia, jak działają wszystkie te funkcje i jak są one powiązane z "tradycyjnym SpringMVC". – Alex

+0

Więc w zasadzie nie chcesz używać Spring Boot lub przynajmniej ciężko pracujesz, aby użyć go jak najmniej. Ale jeśli naprawdę musisz porzucić swój "WebInitializer" i zastąpić go rozszerzeniem klasy 'SpringBootServletInitializer'. –

Odpowiedz

6

Po spędzeniu jednego dnia na badaniach, w końcu znalazłem rozwiązanie mojego problemu. Przede wszystkim musiałem zmodyfikować moje EntityManagerFactory() i transactionManager() fasola:

@Bean 
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() { 
     LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); 
     factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); 
     factory.setPackagesToScan("foo.bar.web.domain"); 
     factory.setDataSource(dataSource()); 
     factory.setJpaPropertyMap(new HashMap<String, Object>() {{ 
      put("hibernate.dialect", dialect); 
      put("hibernate.hbm2ddl.auto", hbm2ddl); 
     }}); 
     factory.afterPropertiesSet(); 
     return factory; 
    } 

    @Bean 
    public PlatformTransactionManager transactionManager() { 
     JpaTransactionManager transactionManager = new JpaTransactionManager(); 
     transactionManager.setEntityManagerFactory(entityManagerFactory().getObject()); 
     return transactionManager; 
    } 

Również całkowicie zdjąłem WebInitializer klasę i usunięte @EnableWebMvc adnotacji z MvcConfig. W Spring-Boot nie ma możliwości rozszerzenia klasy z WebMvcConfigurerAdapter w ścieżce klas, ponieważ jeśli uruchomi się Spring-Boot, cała automatyczna konfiguracja związana z SpringMVC zostanie pominięta. Oto ostateczna wersja mojego MvcConfig klasy:

@Configuration 
@ComponentScan("foo.bar.web.controller") 
public class MvcConfig { 

    @Bean 
    public MultipartResolver multipartResolver() { 
     return new CommonsMultipartResolver(); 
    } 
} 

użyłem wersji wiosenno-Boot klasy aplikacji, który pokazany na Doc:

@SpringBootApplication(exclude = MultipartAutoConfiguration.class) 
public class Application extends SpringBootServletInitializer { 

    public static void main(String[] args) throws Exception { 
     SpringApplication.run(Application.class, args); 
    } 

    @Override 
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 
     return application.sources(Application.class); 
    } 
} 

uwaga, że ​​w moim przypadku musiałem wyłączyć MultipartAutoConfiguration z automatycznej konfiguracji, ponieważ mam już tę funkcję skonfigurowaną w MvcConfig. Bun jest również możliwe pozostawienie go w autokonfiguracji, ale w tym przypadku musiałem dostroić dozwolony rozmiar pliku w pliku konfiguracyjnym application.properties lub dodać komponent MultipartConfigElement do mojej ścieżki klasy.

Powiązane problemy