У меня есть код 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 '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.
$° 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()
Здесь 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 - что приводит к исключению и вопросу, почему методы не найдены.в прокси?