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>
我有一个 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 providinguse-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>