java - 如何在Web应用程序中正确激活spring配置文件

标签 java spring

我正在尝试在我的 Web 应用程序中配置两个不同的配置类 - 一个使用 jdbc,另一个使用 hibernate。我定义了我的配置类,如下所示:

@Profile("jdbc")
@Configuration
public class JdbcConfiguration {
  ...
}


@Profile("hibernate")
@Configuration
public class HibernateConfiguration {
   ...
}

我还有两个主要配置类。一个用于服务,另一个定义 jdbc 和 hibernate 配置类所需的一些数据库基础结构(例如,数据源 bean)。以下是这些类:

@Import({JdbcConfiguration.class, HibernateConfiguration.class})
@Configuration
@EnableTransactionManagement
@PropertySource("classpath:/db.properties")
public class DataAccessConfiguration {
   ...
}



@Configuration
@Import(DataAccessConfiguration.class)
@ComponentScan(basePackages = {"domain.validation","services"})
public class ServiceConfiguration {

    private final UserDao userDao;

    private final GroupDao groupDao;

    private final TaskDao taskDao;

    public ServiceConfiguration(UserDao userDao, GroupDao groupDao, TaskDao taskDao) {
        this.userDao = userDao;
        this.groupDao = groupDao;
        this.taskDao = taskDao;
    }
    ...
}

我想做的是 DataAccessConfiguration 导入 jdbc 和 hibernate 配置。如果 jdbc 配置文件处于 Activity 状态,则只应创建 jdbc 配置中的 bean。否则(如果 hibernate 配置文件处于 Activity 状态),hibernate 的 bean 应该然后我将 DataAccessConfig 导入 ServiceConfiguration,它在服务中使用 dao beans。 我在文档中读到,为了激活 Web 应用程序中的配置文件,我需要在 web.xml 中定义上下文参数 spring.profiles.active 或在启动时以编程方式将其添加到 servletContext。我做了前者。这是我的 web。 xml

<web-app metadata-complete="false" version="4.0" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
   http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" >
  <display-name>Easy Do Web</display-name>

  <context-param>
    <param-name>spring.profiles.active</param-name>
    <param-value>jdbc</param-value>
  </context-param>


</web-app>

我不确定这是否重要,但我通过扩展 AbstractAnnotationConfigDispatcherServletInitializer 来配置我的 servletdispatcher 。

当我尝试启动我的应用程序时遇到的错误是:

02-Jan-2020 13:29:46.070 INFO [RMI TCP Connection(2)-127.0.0.1] org.apache.catalina.core.ApplicationContext.log 2 Spring WebApplicationInitializers detected on classpath
02-Jan-2020 13:29:48.973 SEVERE [RMI TCP Connection(2)-127.0.0.1] org.apache.catalina.core.StandardContext.listenerStart Exception sending context initialized event to listener instance of class [listeners.ContListener]
    org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'serviceConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'repository.UserDao' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:787)
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:226)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1358)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1204)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:400)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207)
        at org.springframework.context.support.AbstractApplicationContext.initMessageSource(AbstractApplicationContext.java:732)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
        at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:89)
        at listeners.ContListener.contextInitialized(ContListener.java:37)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4685)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5146)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:717)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:690)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:705)
        at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1728)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:289)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
        at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:456)
        at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:405)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:289)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
        at com.sun.jmx.remote.security.MBeanServerAccessController.invoke(MBeanServerAccessController.java:468)
        at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468)
        at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
        at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1408)
        at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)
        at sun.rmi.transport.Transport$1.run(Transport.java:200)
        at sun.rmi.transport.Transport$1.run(Transport.java:197)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
    Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'repository.UserDao' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1695)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1253)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207)
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:874)
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:778)
        ... 69 more
02-Jan-2020 13:29:48.974 INFO [RMI TCP Connection(2)-127.0.0.1] org.apache.catalina.core.ApplicationContext.log Initializing Spring root WebApplicationContext
02-Jan-2020 13:29:52.700 INFO [RMI TCP Connection(2)-127.0.0.1] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext

这是完整的jdbc配置类(在hibernate配置中定义了相同的三个dao bean,只是类不同):

@Profile("jdbc")
@Configuration
public class JdbcConfiguration {

    private final DataSource dataSource;

    public JdbcConfiguration(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Bean(name = "userDao")
    public UserDao userDao(NamedParameterJdbcTemplate template){
        return new UserDaoSpringJdbc(dataSource,template);
    }

    @Bean(name = "groupDao")
    public GroupDao groupDao(UserDao userDao,NamedParameterJdbcTemplate template){
        return new GroupDaoSpringJdbc(dataSource,userDao,template);
    }

    @Bean(name="taskDao")
    public TaskDao taskDao(UserDao userDao,GroupDao groupDao,NamedParameterJdbcTemplate template){
        return new TaskDaoSpringJdbc(dataSource,userDao,groupDao,template);
    }

    @Bean
    NamedParameterJdbcTemplate template() {
        return new NamedParameterJdbcTemplate(dataSource);
    }


    @Bean(name = "transactionManager")
    PlatformTransactionManager jdbcTransactionManager() {
        DataSourceTransactionManager manager = new DataSourceTransactionManager();
        manager.setDataSource(dataSource);

        return manager;
    }



}

最佳答案

即使我们不需要 @imported,您的配置看起来也不错,因为它与 xml 方式的 bean 配置非常相似。

根据堆栈跟踪, repository.UserDao bean 不是在 spring 上下文中创建的。

Spring 上下文中没有定义 UserDao bean 来执行此操作。 解决方案是通过注释在 spring 上下文中创建/注册 userDao bean 带有 @Repository 的 UserDao 类。

关于java - 如何在Web应用程序中正确激活spring配置文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59562791/

相关文章:

Java 加密将原始字节转换为公钥,反之亦然

java - 为子类传递构造函数参数时出现"Could not resolve matching constructor"错误

java - Hibernate关系一对一

spring - JsonParseException : Invalid JSON input. 位置 : 9. 字符: '.'

java - Java 中多个操作数的按位异或

java - 吉斯。注入(inject)构造函数

java - 无法 Autowiring 字段 spring-boot

Android HttpUrlConnection 无法发布 - 错误 403

java - 如何用java检查mysql中的id是否已经存在

java - 什么情况下JVM会重启