Почему моя смешанная конфигурация Spring 3.2 приводит к исключению? - PullRequest
1 голос
/ 25 сентября 2019

У меня есть код Spring 3.2, для которого я изменил конфигурацию xml (большую часть) на конфигурацию java.Также есть некоторые аннотации @Component для некоторых bean-компонентов.

В файле web.xml он начинается с:

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<listener>
  <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>

<context-param>
  <param-name>contextClass</param-name>
  <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>com.tms.core.configuration</param-value>
 </context-param>

Затем у нас есть следующая конфигурация java (com.tms.configurations):

@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.tms.core")
@ImportResource({"classpath:applicationContext.xml"})
@EnableTransactionManagement(order = 35)
@PropertySource(value = {"classpath:applicationContext.properties"})
public class TMSApplicationConfig
 {
  @Autowired(required = true)
  private ApplicationContext ctx;


  @Bean
  public JpaTransactionManager transactionManager()
   {
    return new JpaTransactionManager(this.ctx.getBean("entityManagerFactory", LocalContainerEntityManagerFactoryBean.class).getNativeEntityManagerFactory());
   }

  /*
  @Bean(destroyMethod = "close")
  public BasicDataSource dataSource()
   {
    final BasicDataSource dataSource = new BasicDataSource();
    dataSource.setDriverClassName(this.ctx.getEnvironment().getProperty("jdbc.driverClassName"));
    dataSource.setUrl(this.ctx.getEnvironment().getProperty("jdbc.url"));
    dataSource.setUsername(this.ctx.getEnvironment().getProperty("jdbc.username"));
    dataSource.setPassword(this.ctx.getEnvironment().getProperty("jdbc.password"));
    dataSource.setMaxTotal(Integer.parseInt(this.ctx.getEnvironment().getProperty("jdbc.maxConnections")));
    dataSource.setPoolPreparedStatements(false);
    return dataSource;
   }
  */

  // [...]
 }

Также у нас есть applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd" default-autowire="byType">

  <mvc:annotation-driven validator="validator" />

  <bean id="placeholderConfig" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer" p:fileEncoding="UTF-8" p:location="classpath:applicationContext.properties">
    <property name="propertiesPersister">
      <bean class="com.tms.core.common.EncryptedPropertiesReader" />
    </property>
  </bean>

  <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource" p:basenames="classpath:/tms-messages,classpath:/tms-labels" p:cacheSeconds="1" p:useCodeAsDefaultMessage="true" p:fallbackToSystemLocale="false">
    <property name="defaultEncoding" value="UTF-8"/>
  </bean>

  <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
    <property name="validationMessageSource" ref="messageSource"/>
  </bean>

  <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}" p:maxTotal="${jdbc.maxConnections}" p:poolPreparedStatements="false" />

  <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" p:dataSource-ref="dataSource">
    <property name="jpaVendorAdapter">
      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" p:database="${jdbc.database}" p:showSql="false" p:generateDdl="${jdbc.generateDdl}" />
    </property>
  </bean>

  <!-- ... -->
</beans>

Последний, но не менее важный компонент::

@Component
public class ServiceExecutionContext
 {
  @Autowired
  public ServiceExecutionContext(final DataSource dataSource, final PlatformTransactionManager transactionManager, final IUserManager userManager, final IDocumentManager documentManager)
   {
    super();
     // [...]
   }
 }

Проблема в том, что яполучите следующее исключение:

$° WARN° 2019-09-26T11:13:40,825° main° ° org.springframework.web.context.support.AnnotationConfigWebApplicationContext° Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name &apos;serviceExecutionContext&apos; defined in file [C:\Program Files\Apache Software Foundation\Tomcat 9.0\webapps\ROOT\WEB-INF\classes\com\tms\core\service\ServiceExecutionContext.class]: Unsatisfied dependency expressed through constructor argument with index 1 of type [org.springframework.transaction.PlatformTransactionManager]: : Error creating bean with name &apos;transactionManager&apos; defined in class path resource [com&#x2F;tms&#x2F;core&#x2F;configuration&#x2F;TMSApplicationConfig.class]: No matching factory method found: factory bean &apos;TMSApplicationConfig&apos;; factory method &apos;transactionManager()&apos;. Check that a method with the specified name exists and that it is non-static.; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name &apos;transactionManager&apos; defined in class path resource [com&#x2F;tms&#x2F;core&#x2F;configuration&#x2F;TMSApplicationConfig.class]: No matching factory method found: factory bean &apos;TMSApplicationConfig&apos;; factory method &apos;transactionManager()&apos;. Check that a method with the specified name exists and that it is non-static.
$° ERROR° 2019-09-26T11:13:40,841° main° ° org.springframework.web.context.ContextLoader° Context initialization failed org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'serviceExecutionContext' defined in file [C:\Program Files\Apache Software Foundation\Tomcat 9.0\webapps\ROOT\WEB-INF\classes\com\tms\core\service\ServiceExecutionContext.class]: Unsatisfied dependency expressed through constructor argument with index 1 of type [org.springframework.transaction.PlatformTransactionManager]: : Error creating bean with name 'transactionManager' defined in class path resource [com/tms/core/configuration/TMSApplicationConfig.class]: No matching factory method found: factory bean 'TMSApplicationConfig'; factory method 'transactionManager()'. Check that a method with the specified name exists and that it is non-static.; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class path resource [com/tms/core/configuration/TMSApplicationConfig.class]: No matching factory method found: factory bean 'TMSApplicationConfig'; factory method 'transactionManager()'. Check that a method with the specified name exists and that it is non-static.
  at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:752)
  at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:193)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1077)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:981)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
  at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:638)
  at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:942)
  at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
  at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:410)
  at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
  at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
  at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4663)
  at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5131)
  at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
  at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:713)
  at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:690)
  at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:695)
  at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1133)
  at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1868)
  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
  at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
  at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:1045)
  at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:429)
  at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1577)
  at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:309)
  at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)
  at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:424)
  at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:367)
  at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:934)
  at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:831)
  at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
  at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1382)
  at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1372)
  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
  at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
  at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:907)
  at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262)
  at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
  at org.apache.catalina.core.StandardService.startInternal(StandardService.java:423)
  at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
  at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:933)
  at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
  at org.apache.catalina.startup.Catalina.start(Catalina.java:637)
  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.catalina.startup.Bootstrap.start(Bootstrap.java:350)
  at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:492)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class path resource [com/tms/core/configuration/TMSApplicationConfig.class]: No matching factory method found: factory bean 'TMSApplicationConfig'; factory method 'transactionManager()'. Check that a method with the specified name exists and that it is non-static.
  at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:550)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1057)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:953)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
  at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:923)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:866)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:781)
  at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:818)
  at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:745)
  ... 56 more

Как вы можете видеть, метод TransactionManager () существует в TMSApplicationConfig и также не является статическим.

Я уже пытался понять источник в github , чтобы узнать больше о проблеме, но без удачи.

Что я не совсем понимаю, так это пример dataSource - что при включении его в конфигурации Java (и отключить его)в xml) это приведет к тому же самому исключению - и при перемещении его обратно в xml он будет работать.

Так что мне кажется, что классы, помеченные как xml, и компоненты не имеют доступа к конфигурации Javaно почему?Я думал, что все это будет в одной конфигурации для внутреннего использования?

Любая помощь будет признательна.

ОБНОВЛЕНИЕ 1:

Я сейчас исправилОбработка ApplicationContext (как упомянуто @M. Deinum), но исключение остается тем же.

ОБНОВЛЕНИЕ 2:

Добавлена ​​полная трассировка стека.Удалено управление XML tx.Отлаженная пружина 3.2.18 ConstructorResolver.instantiateUsingFactoryMethod()

enter image description here

Здесь beanName правильно, также factoryBeanName правильно.Но что приводит к ошибке, так это то, что сам factoryBean является прокси-сервером - и этот прокси-сервер не имеет имен методов из TMSApplicationConfig, поэтому не удалось найти метод beanName'actionManager '.

Добавлена ​​важная частьЗависимости maven (исключенные исключения):

  <properties>
    <springVersion>3.2.18.RELEASE</springVersion>
    <springSecurityVersion>3.2.10.RELEASE</springSecurityVersion>
  </properties>


  <dependencies>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>javax.inject</groupId>
      <artifactId>javax.inject</artifactId>
      <version>1</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${springVersion}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${springVersion}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${springVersion}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${springVersion}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${springVersion}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${springVersion}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${springVersion}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>${springVersion}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>${springVersion}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-core</artifactId>
      <version>${springSecurityVersion}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-config</artifactId>
      <version>3.2.10.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-web</artifactId>
      <version>3.2.10.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-taglibs</artifactId>
      <version>${springSecurityVersion}</version>
    </dependency>

    <dependency>
      <groupId>org.thymeleaf</groupId>
      <artifactId>thymeleaf</artifactId>
      <version>3.0.11.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>4.3.2.Final</version> 
    </dependency>

    <dependency>
      <groupId>javax.el</groupId>
      <artifactId>javax.el-api</artifactId>
      <version>3.0.1-b06</version>
    </dependency>

    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>javax.el</artifactId>
      <version>3.0.1-b11</version>
    </dependency>

    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>4.2.21.Final</version>
    </dependency>

    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>4.2.21.Final</version>
    </dependency>

    <dependency>
      <groupId>javax.transaction</groupId>
      <artifactId>jta</artifactId>
      <version>1.1</version>
    </dependency>

ОБНОВЛЕНИЕ 3

Исключена конфигурация из сканирования компонентов.Также сделаны более явными возвращаемые типы конфигурации.Удалены исключения из зависимостей (только здесь, потому что вопрос был слишком большим).

Из отладки еще немного информации:

Сгенерированный класс Proxy: com.tms.configuration.TMSApplicationConfig$$EnhancerBySpringCGLIB$$fe47f862@498ae73c

Методы, найденные ConstructorResolver.instantiateUsingFactoryMethod(), следующие:

Proxy.newProxyInstance(java.lang.ClassLoader,java.lang.Class[],java.lang.reflect.InvocationHandler)
Proxy.isProxyClass(java.lang.Class),
Proxy.getProxyClass0(java.lang.ClassLoader,java.lang.Class[]),
Proxy.getProxyClass(java.lang.ClassLoader,java.lang.Class[])
Proxy.getInvocationHandler(java.lang.Object)
Proxy.defineClass0(java.lang.ClassLoader,java.lang.String,byte[],int,int),
Proxy.checkProxyAccess(java.lang.Class,java.lang.ClassLoader,java.lang.Class[]),
Proxy.checkNewProxyPermission(java.lang.Class,java.lang.Class),
Proxy.access$300(java.lang.ClassLoader,java.lang.String,byte[],int,int),
Proxy.access$200(),
Object.wait(long,int) throws java.lang.InterruptedException,
Object.wait(long
Object.wait() throws java.lang.InterruptedException,
Object.toString(),
Object.registerNatives()´
Object.notifyAll(),
Object.notify(),
Object.hashCode(),
Object.getClass(),
Object.finalize() throws java.lang.Throwable,
Object.equals(java.lang.Object),
Object.clone() throws java.lang.CloneNotSupportedException,
$Proxy76.toString(), 
$Proxy76.toProxyConfigString(),
$Proxy76.setTargetSource(org.springframework.aop.TargetSource),
$Proxy76.setPreFiltered(boolean),
$Proxy76.setExposeProxy(boolean),
$Proxy76.replaceAdvisor(org.springframework.aop.Advisor,org.springframework.aop.Advisor)
$Proxy76.removeAdvisor(org.springframework.aop.Advisor),
$Proxy76.removeAdvisor(int) 
$Proxy76.removeAdvice(org.aopalliance.aop.Advice),
$Proxy76.isProxyTargetClass(),
$Proxy76.isPreFiltered(),
$Proxy76.isInterfaceProxied(java.lang.Class),
$Proxy76.isFrozen(),
$Proxy76.isExposeProxy(),
$Proxy76.indexOf(org.springframework.aop.Advisor),
$Proxy76.indexOf(org.aopalliance.aop.Advice),
$Proxy76.hashCode(), 
$Proxy76.getTargetSource(),
$Proxy76.getTargetClass(),
$Proxy76.getProxiedInterfaces(),
$Proxy76.getAdvisors(),
$Proxy76.equals(java.lang.Object), 
$Proxy76.destroy() throws java.lang.Exception,
$Proxy76.addAdvisor(org.springframework.aop.Advisor)
$Proxy76.addAdvisor(int,org.springframework.aop.Advisor)
$Proxy76.addAdvice(org.aopalliance.aop.Advice)
$Proxy76.addAdvice(int,org.aopalliance.aop.Advice)

Итак, как я сказал в прокси-сервере, нет методов из исходного класса TMSApplicationConfiguration - что приводит к исключению и вопросу, почему методы не найдены.в прокси?

...