Spring 过滤自动扫描中的组件

Spring Filter components in auto scanning

我有一个 Spring MVC 应用程序。 ( Java 平台的应用程序框架和控制反转容器。任何 Java 应用程序都可以使用该框架的核心功能,但也有用于在 [=32= 之上构建 Web 应用程序的扩展] EE(企业版)平台)使用这个Spring过滤,现在使用spring过滤器

 <context:component-scan base-package="com.pastis"  >
    <context:exclude-filter type="assignable" expression="com.pastis.security.controller.SecurityManagerController"/>
    <context:exclude-filter type="assignable" expression="com.pastis.pq.workflow.web.controller.WorkflowController"/>
    <context:exclude-filter type="regex"      expression="com.pastis.pq.workflow.web.*" />
    <context:exclude-filter type="regex"      expression="com.pastis.security.*" />
    <context:exclude-filter type="regex"      expression="com\.pastis\.security\..*" />
</context:component-scan>

<jpa:repositories base-package="com.pastis.repositories"/>

也试过:

<context:annotation-config />
    <context:component-scan base-package="com.pastis" />
    <context:component-scan base-package="com.pastis.security">
        <context:exclude-filter type="assignable" expression="com.pastis.security.controller.SecurityManagerController"/>
    </context:component-scan>
    <context:component-scan base-package=" com.pastis.pq">
        <context:exclude-filter type="assignable" expression="com.pastis.pq.workflow.web.controller.WorkflowController"/>
        <context:exclude-filter type="assignable" expression="com.pastis.pq.workflow.web.controller.WorkflowAdminController"/>
    </context:component-scan>

但我对 WorkflowController

有疑问

和这个控制器:

com.pastis.security.controller.SecurityManagerController

然而,当我启动应用程序时。我收到此错误:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityManagerController':

servlet-xml:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:jpa="http://www.springframework.org/schema/data/jpa"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/data/jpa
   http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- Use annotations to inject stuff -->
    <context:annotation-config />
    <context:component-scan base-package="com.pastis.pq" use-default-filters="false" >
        <context:include-filter type="aspectj" expression="com.pastis.pq.web.endpoint.*" />
        <!--context:include-filter type="annotation" expression="com.pastis.pq.web."-/-->
    </context:component-scan>

    <jpa:repositories base-package="com.pastis.pq.repositories"/>

    <!-- main datasource -->
    <bean id="dataSource"
            class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.h2.Driver" />
        <property name="url" value="jdbc:h2:mem:~/test2;DB_CLOSE_DELAY=-1 />
        <property name="username" value="sa" />
        <property name="password" value="" />
    </bean>

    <!-- transaction management -->
    <tx:annotation-driven/>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <!-- spring data repositories -->
    <jpa:repositories base-package="com.pastis.pq.repositories"/>

    <bean id="jpaVendorAdapter"
              class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">

        <property name="database" value="H2" />
        <property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
    </bean>

    <bean id="entityManagerFactory"
              class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="persistenceUnitName" value="pastis-entities" />
        <property name="packagesToScan">
            <array>
              <value>com.pastis.pq.model</value>
            </array>
        </property>
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
        <property name="jpaProperties">
            <props>
                <prop key="eclipselink.target-database">org.eclipse.persistence.platform.database.OraclePlatform</prop>
                <prop key="eclipselink.target-server">WebLogic</prop>
            </props>
        </property>
    </bean>

    <!-- customizable database configuration -->
    <bean id="dataConfig" class="com.pastis.commons.services.SystemConfig">
        <constructor-arg index="0" value="test-config.properties"/>
        <constructor-arg index="1" ref="dataSource"/>
    </bean>

 
       
</beans>

我 运行 测试时的控制台:

2020-10-08 10:46:57,315 [DEBUG] org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'securityManagerController'
2020-10-08 10:46:57,315 [DEBUG] org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'securityManagerController'
2020-10-08 10:46:57,315 [DEBUG] org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'securityManagerController'
2020-10-08 10:46:57,315 [DEBUG] org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'securityManagerController'
2020-10-08 10:46:57,317 [DEBUG] org.springframework.beans.factory.annotation.InjectionMetadata - Registered injected element on class [com.pastis.security.controller.SecurityManagerController]: 

您的初始代码片段是正确的,但您没有为组件扫描定义正确的包。

如果您要排除的 class 是这样的:

com.pastis.security.controller.SecurityManagerController

而不是这个 XML 片段:

<context:annotation-config />
<context:component-scan base-package="com.pastis.pq"  >
    <context:exclude-filter type="assignable" expression="com.pastis.security.controller.SecurityManagerController"/>
</context:component-scan>

<jpa:repositories base-package="com.pastis.pq.repositories"/>

你需要这样的东西:

<context:annotation-config />
<context:component-scan base-package="com.pastis">
    <context:exclude-filter type="assignable" expression="com.pastis.security.controller.SecurityManagerController"/>
</context:component-scan>

<jpa:repositories base-package="com.pastis.pq.repositories"/>

请注意包名称从 com.pastis.pq 更改为 com.pastis

或者更好的是,为此目的定义另一个 component-scan 元素:

<context:annotation-config />
<context:component-scan base-package="com.pastis.pq" />
<context:component-scan base-package="com.pastis.security">
    <context:exclude-filter type="assignable" expression="com.pastis.security.controller.SecurityManagerController"/>
</context:component-scan>

<jpa:repositories base-package="com.pastis.pq.repositories"/>

请不要忘记从 <context:component-scan> 元素中删除属性 use-default-filters="false"。如documentation中所示:

You can also disable the default filters by setting useDefaultFilters=false on the annotation or providing use-default-filters="false" as an attribute of the <component-scan/> element. This will in effect disable automatic detection of classes annotated with @Component, @Repository, @Service, @Controller, or @Configuration.

这很可能是您尝试的其中一种方法 Spring 无法识别 com.pastis.pq.web.endpoint.* 包中的 bean 的原因。

只要你还在使用<context:component-scan>,可能你就可以去掉<context:annotation-config>这个元素。请在 Whosebug 中查看 this great answer

更新

经过问题的不同修改,我认为这个XML配置应该可以正常工作:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:jpa="http://www.springframework.org/schema/data/jpa"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/data/jpa
   http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <context:component-scan base-package="com.pastis.pq">
        <context:exclude-filter type="assignable" expression="com.pastis.pq.workflow.web.controller.WorkflowController"/>
        <context:exclude-filter type="assignable" expression="com.pastis.pq.workflow.web.controller.WorkflowAdminController"/>
    </context:component-scan>

    <context:component-scan base-package="com.pastis.security">
        <context:exclude-filter type="assignable" expression="com.pastis.security.controller.SecurityManagerController"/>
    </context:component-scan>

    <jpa:repositories base-package="com.pastis.pq.repositories"/>

    <!-- main datasource -->
    <bean id="dataSource"
            class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.h2.Driver" />
        <property name="url" value="jdbc:h2:mem:~/test2;DB_CLOSE_DELAY=-1 />
        <property name="username" value="sa" />
        <property name="password" value="" />
    </bean>

    <!-- transaction management -->
    <tx:annotation-driven/>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <!-- spring data repositories -->
    <jpa:repositories base-package="com.pastis.pq.repositories"/>

    <bean id="jpaVendorAdapter"
              class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">

        <property name="database" value="H2" />
        <property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
    </bean>

    <bean id="entityManagerFactory"
              class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="persistenceUnitName" value="pastis-entities" />
        <property name="packagesToScan">
            <array>
              <value>com.pastis.pq.model</value>
            </array>
        </property>
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
        <property name="jpaProperties">
            <props>
                <prop key="eclipselink.target-database">org.eclipse.persistence.platform.database.OraclePlatform</prop>
                <prop key="eclipselink.target-server">WebLogic</prop>
            </props>
        </property>
    </bean>

    <!-- customizable database configuration -->
    <bean id="dataConfig" class="com.pastis.commons.services.SystemConfig">
        <constructor-arg index="0" value="test-config.properties"/>
        <constructor-arg index="1" ref="dataSource"/>
    </bean>

</beans>