0

在 Spring 4.3.5 中,我们一直在使用一种应用程序架构,在该架构中我们一次性初始化一些 bean,然后将这些 bean 用作其他 bean 的“参考”。

像这样的东西

<bean id="handleUncheckedEndpointExceptionAdvice" 
    class="com.gehcit.cp.ws.infrastructure.aop.advices.HandleUncheckedEndpointExceptionAdvice">
    <constructor-arg ref="exceptionFactory"/>
    <property name="exceptionSenderService" ref="exceptionSenderService" />
</bean>

但是一旦我们将库升级到 Spring 5.2.x,我们开始在 Jboss 7.3.1 启动时遇到以下异常:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'handleUncheckedEndpointExceptionAdvice' defined in ServletContext resource [/WEB-INF/context-web.xml]: Cannot resolve reference to bean 'exceptionSenderService' while setting bean property 'exceptionSenderService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'exceptionSenderService' available

我所做的一切: 启用 TRACE 日志记录并发现这一点 -2022-03-05 13:09:39,927 TRACE [org.springframework.beans.factory.annotation.InjectionMetadata] (ServerService Thread Pool -- 65) Processing injected element of bean 'exceptionSenderService': AutowiredFieldElement for private com.gehcit.cp.serviceability.service.ExceptionSenderService com.gehcit.cp.cem.aplix.jms.service.Impl.AplixPublisherQueueServiceImpl.exceptionSender 2022-03-05 13:09:39,927 TRACE [org.springframework.beans.factory.support.DefaultListableBeanFactory] (ServerService Thread Pool -- 65) Returning cached instance of singleton bean 'exceptionSenderServiceImpl' 2022-03-05 13:09:39,927 TRACE [org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor] (ServerService Thread Pool -- 65) Autowiring by type from bean name 'exceptionSenderService' to bean named 'exceptionSenderServiceImpl' 现在 bean 正在初始化,但是当搜索引用时,从 Spring 缓存中搜索,我们什么也得不到。

但是后来我们尝试将 bean 初始化从不同的 xml 转移到 bean 被引用的相同 xml 并且有效。所以我们得出结论,不知何故,跨 XML 配置不起作用。

从 context-web.xml 引用的 Bean

<?xml version="1.0"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:util="http://www.springframework.org/schema/util" 
    xmlns:cxf="http://cxf.apache.org/core" 
    xmlns:jaxws="http://cxf.apache.org/jaxws" 
    xmlns:jaxrs="http://cxf.apache.org/jaxrs" 
    xmlns:task="http://www.springframework.org/schema/task" 
    xmlns:security="http://www.springframework.org/schema/security"
    xmlns:oauth2="http://www.springframework.org/schema/security/oauth2" 
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
        http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
        http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
        http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
        http://www.springframework.org/schema/security 
            https://www.springframework.org/schema/security/spring-security.xsd
        http://www.springframework.org/schema/security/oauth2 
            https://www.springframework.org/schema/security/spring-security-oauth2.xsd">

    <task:annotation-driven/>
    <!-- Define placeholder for application properties -->
    <bean 
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>/WEB-INF/web.properties</value>
                <value>classpath:application.properties</value>
            </list>
        </property>
    </bean>
    <!-- Load CXF modules from cxf.jar -->
    <import resource="classpath:META-INF/cxf/cxf.xml"/>
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
    <import resource="context-cem-web.xml"/>
    <!-- define an auto-proxy generator for our advisors -->
    <bean 
        class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
        <property name="proxyTargetClass" value="false"/>
    </bean>
    <!-- id generator for exceptions -->
    <bean id="exceptionIdGenerator" 
        class="com.gehcit.cp.ws.infrastructure.exception.HostTimeExceptionIdGenerator">
        <property name="prefix" value="CEN"/>
    </bean>
    <!-- system fault factory -->
    <bean id="systemFaultFactory" 
        class="com.gehcit.cp.ws.infrastructure.exception.StandardSystemFaultFactory">
        <property name="exceptionIdGenerator" ref="exceptionIdGenerator"/>
        <property name="appendExceptionIdToErrorMessage" value="true"/>
    </bean>
    <bean id="defaultParamConverterProvider"
        class="org.apache.cxf.jaxrs.ext.search.DefaultParamConverterProvider"/>
    <!-- factory for mapping runtime exceptions to wire faults -->
    <bean id="exceptionFactory" 
        class="com.gehcit.cp.ws.infrastructure.exception.ExceptionMapperExceptionFactory">
        <property name="exceptionMappers">
            <list>
                <bean 
                    class="com.gehcit.cp.ws.infrastructure.exception.IllegalArgumentFaultFromIllegalArgumentExceptionMapper"/>
                <bean 
                    class="com.gehcit.cp.ws.infrastructure.exception.SecurityFaultFromCPSecurityExceptionMapper"/>
                <bean 
                    class="com.gehcit.cp.ws.infrastructure.exception.ApplicationFaultFromApplicationErrorMapper"/>
                <bean 
                    class="com.gehcit.cp.ws.infrastructure.exception.SystemFaultFromRuntimeExceptionMapper">
                    <constructor-arg ref="systemFaultFactory"/>
                </bean>
            </list>
        </property>
    </bean>
    <!-- aspect for handling unchecked endpoint exceptions -->
    <bean id="handleUncheckedEndpointExceptionAdvice" 
        class="com.gehcit.cp.ws.infrastructure.aop.advices.HandleUncheckedEndpointExceptionAdvice">
        <constructor-arg ref="exceptionFactory"/>
        <property name="exceptionSenderService" ref="exceptionSenderService" />
    </bean>
    <bean id="handleUncheckedEndpointExceptionPointcut" 
        class="org.springframework.aop.support.annotation.AnnotationMatchingPointcut">
        <constructor-arg type="java.lang.Class">
            <null/>
        </constructor-arg>
        <constructor-arg type="java.lang.Class" 
            value="com.gehcit.cp.ws.infrastructure.aop.annotations.HandleUncheckedEndpointException"/>
    </bean>
    <bean id="handleUncheckedEndpointExceptionAdvisor" 
        class="org.springframework.aop.support.DefaultPointcutAdvisor">
        <property name="advice" ref="handleUncheckedEndpointExceptionAdvice"/>
        <property name="pointcut" 
            ref="handleUncheckedEndpointExceptionPointcut"/>
    </bean>

bean 正在 context-applix.xml 中初始化

    <beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:amq="http://activemq.apache.org/schema/core" 
    xmlns:jms="http://www.springframework.org/schema/jms" 
    xmlns:p="http://www.springframework.org/schema/p" 
    xsi:schemaLocation="
                  http://www.springframework.org/schema/beans 
                  http://www.springframework.org/schema/beans/spring-beans.xsd
                  http://activemq.apache.org/schema/core
                  http://activemq.apache.org/schema/core/activemq-core.xsd
                  http://www.springframework.org/schema/beans 
                  http://www.springframework.org/schema/beans/spring-beans.xsd
                  http://www.springframework.org/schema/jms 
                  http://www.springframework.org/schema/jms/spring-jms.xsd">
    <!-- Activemq connection factory start -->
    <bean id ="connectionAmqFactory" 
        class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" 
            value="vm://broker#{T(com.gehcit.cp.ws.ServiceProperties).instance().getProperty(T(com.gehcit.cp.Constants).CENTRICITY_DEPLOY_ID)}-applix" 
            />
    </bean>
    <!-- A POJO that implements the JMS message listener -->
    <bean id="aplixSubscriberQueueService" 
        class="com.gehcit.cp.cem.aplix.jms.listener.AplixSubscriberQueueListener" 
        />
    <bean id="exceptionSenderService" 
        class="com.gehcit.cp.cem.aplix.jms.service.Impl.AplixPublisherQueueServiceImpl" 
        />
    <!-- A destination in ActiveMQ -->
    <!--amq:topic id="destination" physicalName="APLIX.ERRORINFO" /-->
    <!-- A destination in ActiveMQ -->
    <amq:queue id="destination" physicalName="APLIX.ERRORINFO" />
    <!-- A destination in ActiveMQ end-->
    <!-- A cached connection to wrap the ActiveMQ connection -->
    <bean id="cachedAmqConnectionFactory" 
        class="org.springframework.jms.connection.CachingConnectionFactory" 
        p:targetConnectionFactory-ref="connectionAmqFactory" 
        p:sessionCacheSize="10" />
    <!-- Adding JMS transaction Manager -->
    
    <bean id="TransactionManager" 
        class="org.springframework.jms.connection.JmsTransactionManager">
        <property name="connectionFactory" ref="cachedAmqConnectionFactory"/>
    </bean>
    <!-- Adding JMS transaction Manager -End -->
    <!-- A JmsTemplate instance that uses the connection and destination -->
    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate" 
        p:connectionFactory-ref="cachedAmqConnectionFactory" 
        p:defaultDestination-ref="destination" />
    <!-- A JmsTemplate instance that uses the connection and destination end -->
    <!--Cofiguring JMS container and listener-->
    <jms:listener-container container-type="default" 
        connection-factory="cachedAmqConnectionFactory" destination-type="queue" >
        <jms:listener destination="APLIX.ERRORINFO" 
            ref="aplixSubscriberQueueService" method="onMessage" />
    </jms:listener-container>
    <!--Cofiguring JMS container and listener end-->
    <!-- The Spring message listener container configuration -->
    <amq:broker start="true" persistent="false" 
        brokerName="broker#{T(com.gehcit.cp.ws.ServiceProperties).instance().getProperty(T(com.gehcit.cp.Constants).CENTRICITY_DEPLOY_ID)}-applix" 
        deleteAllMessagesOnStartup="false" >
        <amq:managementContext>
            <amq:managementContext createConnector="false"/>
        </amq:managementContext>
        <amq:systemUsage>
            <amq:systemUsage>
                <amq:memoryUsage>
                    <amq:memoryUsage limit="512 mb"/>
                </amq:memoryUsage>
                <amq:tempUsage>
                    <amq:tempUsage limit="2 gb"/>
                </amq:tempUsage>
            </amq:systemUsage>
        </amq:systemUsage>      
        <amq:transportConnectors>
            <amq:transportConnector name="vm" 
                uri="vm://broker#{T(com.gehcit.cp.ws.ServiceProperties).instance().getProperty(T(com.gehcit.cp.Constants).CENTRICITY_DEPLOY_ID)}-applix"/>
        </amq:transportConnectors>
    </amq:broker>
</beans>

有人可以帮我找到一种方法来引用 Spring 5.2.x 中其他 xml 文件中的 bean。 注意:我们已经用 Spring 5.2 更改了类加载部分。

将此添加到 web.xml

    <listener-class>com.gehcit.cp.ws.infrastructure.security.BeanFactoryContextLoaderListener</listener-class>
</listener>
<!-- <context-param>
    <param-name>locatorFactorySelector</param-name>
    <param-value>/beanRefFactory.xml</param-value>
</context-param>  -->

BeanFactoryContextLoaderListener.java

package com.gehcit.cp.ws.infrastructure.security;
import javax.servlet.ServletContext;
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.ContextLoaderListener;
public class BeanFactoryContextLoaderListener extends ContextLoaderListener {
private static Logger log = Logger.getLogger(BeanFactoryContextLoaderListener.class)     
    @Override
        protected ApplicationContext loadParentContext(ServletContext servletContext) { 
         log.info("Entered loadParentContext");    
         ApplicationContext ctx = new ClassPathXmlApplicationContext("beanRefFactory.xml");
         log.info("Exit loadParentContext" + ctx.toString());
         return ctx;
        }
}
4

0 回答 0