Spring - bean初始化两次

时间:2018-01-10 19:21:20

标签: java spring spring-mvc

我知道春天的两个背景故事。我了解有两个上下文 - 一个用于ContextLoaderListener,另一个用于DispatcherServlet

我正在尝试使用项目的所有java配置并完全删除web.xml文件。所以我使用AbstractAnnotationConfigDispatcherServletInitializer类。但我正面临着这个问题。当我启动服务器时,我可以看到bean被创建了两次。你能帮我理解,我做错了什么。

正如您所看到的,我为RootConfig文件尝试了不同的注释,以便忽略EnableWebMvc类中引用的Config以及其他一些组合,但它始终会扫描这些类并启动bean。 (请参阅日志行viewResolver calleddatasource bean creation两次打印)

以下是项目详情:

日志

Jan 11, 2018 12:20:57 AM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 5220 ms
INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization started
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Refreshing Root WebApplicationContext: startup date [Thu Jan 11 00:21:37 IST 2018]; root of context hierarchy
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Registering annotated classes: [class com.nikdroid.poc.config.RootConfig]
INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
datasource bean creation
WARN : org.hibernate.engine.jdbc.internal.JdbcServicesImpl - HHH000342: Could not obtain connection to query metadata : Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/],methods=[GET]}" onto public org.springframework.web.servlet.ModelAndView com.nikdroid.poc.controller.HomeController.home()
INFO : org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler]
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - Looking for @ControllerAdvice: Root WebApplicationContext: startup date [Thu Jan 11 00:21:37 IST 2018]; root of context hierarchy
viewResolver called
INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 12563 ms
INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcher': initialization started
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Refreshing WebApplicationContext for namespace 'dispatcher-servlet': startup date [Thu Jan 11 00:21:49 IST 2018]; parent: Root WebApplicationContext
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Registering annotated classes: [class com.nikdroid.poc.config.WebConfig]
INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
datasource bean creation
WARN : org.hibernate.engine.jdbc.internal.JdbcServicesImpl - HHH000342: Could not obtain connection to query metadata : Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/],methods=[GET]}" onto public org.springframework.web.servlet.ModelAndView com.nikdroid.poc.controller.HomeController.home()
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - Looking for @ControllerAdvice: WebApplicationContext for namespace 'dispatcher-servlet': startup date [Thu Jan 11 00:21:49 IST 2018]; parent: Root WebApplicationContext
INFO : org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler]
viewResolver called
INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcher': initialization completed in 2643 ms
Jan 11, 2018 12:22:08 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 71461 ms

和 AbstractAnnotationConfigDispatcherServletInitializer

package com.nikdroid.poc.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

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

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

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

}

WebConfig

package com.nikdroid.poc.config;

import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@EnableWebMvc
/*@ComponentScan("com.nikdroid.poc")*/
/*@ComponentScan(basePackageClasses={ControllerMarker.class, ServiceMarker.class, DaoMarker.class})*/
@ComponentScan(basePackages = "com.nikdroid.poc",
excludeFilters = {
    @Filter(type = FilterType.ASSIGNABLE_TYPE,
            value = {
                WebConfig.class
            })
})
public class WebConfig extends WebMvcConfigurerAdapter {

    @Bean
    public ViewResolver viewResolver() {
        System.out.println("viewResolver called");
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        //resolver.setExposeContextBeansAsAttributes(true);
        return resolver;
    }

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

    @Bean
    public MessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasename("messages");
        return messageSource;
    }

}

RootConfig

package com.nikdroid.poc.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@ComponentScan(basePackages={"com.nikdroid"},
excludeFilters={
    @Filter(type=FilterType.ANNOTATION, value=EnableWebMvc.class)
})
/*@ComponentScan(basePackageClasses={ControllerMarker.class, ServiceMarker.class, DaoMarker.class},
    excludeFilters={
        @Filter(type=FilterType.ANNOTATION, value=EnableWebMvc.class)
    })*/
/*@ComponentScan(basePackages = "com.nikdroid.poc",
excludeFilters = {
    @Filter(type = FilterType.ASSIGNABLE_TYPE,
            value = {
                    com.nikdroid.poc.config.WebConfig.class
            })
})*/
/*@ComponentScan(basePackages = "com.nikdroid.poc", 
excludeFilters = @Filter(type=FilterType.REGEX,pattern="com\\.nikdroid\\.poc\\.config\\..*")) */

/*@ComponentScan("com.nikdroid.poc")*/
public class RootConfig {

}

JPAConfig

package com.nikdroid.poc.config;

import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;


@Configuration
@ComponentScan({ "com.nikdroid.poc" })
@EnableTransactionManagement
@PropertySource(value = { "classpath:application.properties" })
public class JPAConfig {

    @Autowired
    private Environment environment;

    @Bean
    public DataSource dataSource() {
        System.out.println("datasource bean creation");
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
        ds.setUrl(environment.getRequiredProperty("jdbc.url"));
        ds.setUsername(environment.getRequiredProperty("jdbc.username"));
        ds.setPassword(environment.getRequiredProperty("jdbc.password"));
        return ds;
    }

    @Autowired
    @Bean
    public LocalSessionFactoryBean sessionFactory(DataSource dataSource) {
      LocalSessionFactoryBean sfb = new LocalSessionFactoryBean();
      sfb.setDataSource(dataSource);
      sfb.setPackagesToScan(new String[] { "com.nikdroid.poc" });//TODO  find alternate
      sfb.setHibernateProperties(hibernateProperties());
      return sfb;
    }


    private Properties hibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
        properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
        properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
        return properties;        
    }

    @Bean
    @Autowired
    public HibernateTransactionManager transactionManager(SessionFactory s) {
       HibernateTransactionManager txManager = new HibernateTransactionManager();
       txManager.setSessionFactory(s);
       return txManager;
    }
}

0 个答案:

没有答案