spring中关于context:component-scan的使用说明

     https://blog.csdn.net/liuxingsiye/article/details/52171508


  通常情况下我们在创建spring项目的时候在xml配置文件中都会配置这个表情,配置完这个标签后,spring就会去自动扫描base-package对应的路径或者该路径的子包下面的java文件,如果扫描到文件中带有@Service,@Component,@Repository,@Controller等这些注解的类,则把这些类注册为bean

         注:如果配置了<context:component-scan>那么<context:annotation-config/>标签就可以不用在xml中再配置了,因为前者包含了后者。另外<context:annotation-config/>还提供了两个子标签 <context:include-filter>和 <context:exclude-filter>

在注解注入之前也必须在spring的配置文件中做如下配置,我们看下spring.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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="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-3.0.xsd">
	<context:component-scan base-package="com.sparta.trans" use-default-filters="false">  
              <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>      
        </context:component-scan>
 </beans>

这个配置文件中必须声明xmlns:context 这个xml命名空间,在schemaLocation中需要指定schema:

           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.0.xsd
这个文件中beans根节点下只有一个context:component-scan节点,此节点有两个属性base-package属性告诉spring要扫描的包,use-default-filters="false"表示不要使用默认的过滤器,此处的默认过滤器,会扫描包含@Service,@Component,@Repository,@Controller注解修饰的类,use-default-filters属性的默认值为true,这就意味着会扫描指定包下标有@Service,@Component,@Repository,@Controller的注解的全部类,并注册成bean。所以如果仅仅是在配置文件中写<context:component-scan base-package="
com.sparta.trans"/> Use-default-filter此时为true时,那么会对base-package包或者子包下所有的java类进行扫描,并把匹配的java类注册成bean。

 所以这用情况下可以发现扫描的粒度还是挺大的,但是如果你只想扫描指定包下面的Controller,那该怎么办?此时子标签<context:incluce-filter>就可以发挥作用了。如下所示

<context:component-scan base-package="com.sparta.trans.controller">

        <context:include-filter type="regex" expression="com\.sparta\.trans\.[^.]+(Controller|Service)"/>

                 <!--  <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>  -->

</context:component-scan>  

这样就会只扫描base-package指定下的有@Controller下的java类,并注册成bean

注: context:component-scan节点允许有两个子节点<context:include-filter>和<context:exclude-filter>。filter标签的type和表达式说明如下:

 Filter TypeExamples ExpressionDescription
annotationorg.example.SomeAnnotation符合SomeAnnoation的target class
assignableorg.example.SomeClass指定class或interface的全名
aspectjorg.example..*Service+AspectJ語法
regexorg\.example\.Default.*Regelar Expression
customorg.example.MyTypeFilterSpring3新增自訂Type,實作org.springframework.core.type.TypeFilter

在我们的示例中,将filter的type设置成了正则表达式,regex,注意在正则里面.表示所有字符,而\.才表示真正的.字符。我们的正则表示以Controller或者Service结束的类。

我们也可以使用annotaion来限定,如上面注释掉的所示。这里我们指定的include-filter的type是annotation,expression则是注解类的全名。

但是因为use-dafault-filter在上面并没有指定,默认就为true,所以当把上面的配置改成如下所示的时候,就会产生与你期望相悖的结果(注意base-package包值得变化)

<context:component-scan base-package="com.sparta.trans">  

<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>   

</context:component-scan>  

此时,spring不仅扫描了@Controller,还扫描了指定包所在的子包service包下注解@Service的java类

此时指定的include-filter没有起到作用,只要把use-default-filter设置成false就可以了。这样就可以避免在base-packeage配置多个包名来解决这个问题了。

另外在实际项目开发中我们可以发现在base-package指定的包中有的子包是不含有注解的,所以不用扫描,此时可以指定<context:exclude-filter>来进行过滤,说明此包不需要被扫描。所以综上可以看出 use-dafault-filters=”false”的情况下:<context:exclude-filter>可以指定不需要扫描的路径来排除扫描这些文件,<context:include-filter>可以指定需要扫描的路径来进行扫描。但是由于use-dafault-filters的值默认为true,所以这一点在实际使用中还是需要注意一下的。


为什么说我'context:component-scan' 未声明?

09-27

之前使用Spring都是基于xml的装配,最近想学学基于注解的装配,于是就把之前的一个基于xml装配的项目改成了基于注解的,然后就报错:通配符的匹配很全面, 但无法找到元素 'context:component-scan' 的声明。rnapplicationContext.xml中的相关配置如下:rnrnrn rn rn rn //......下面的配置略rnrn服务器启动时,报如下错误:rnorg.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 15 in XML document from class path resource [applicationContext.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 15; columnNumber: 72; cvc-complex-type.2.4.c: 通配符的匹配很全面, 但无法找到元素 'context:component-scan' 的声明。rn at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:396)rn at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)rn at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)rn at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:174)rn at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:209)rn at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)rn at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)rn at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)rn at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:131)rn at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:522)rn at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:436)rn at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:385)rn at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:284)rn at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)rn at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4210)rn at org.apache.catalina.core.StandardContext.start(StandardContext.java:4709)rn at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:799)rn at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:779)rn at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:583)rn at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1079)rn at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:1002)rn at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:506)rn at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1317)rn at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:324)rn at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:142)rn at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1065)rn at org.apache.catalina.core.StandardHost.start(StandardHost.java:822)rn at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)rn at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)rn at org.apache.catalina.core.StandardService.start(StandardService.java:525)rn at org.apache.catalina.core.StandardServer.start(StandardServer.java:754)rn at org.apache.catalina.startup.Catalina.start(Catalina.java:595)rn at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)rn at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)rn at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)rn at java.lang.reflect.Method.invoke(Method.java:606)rn at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)rn at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)rnCaused by: org.xml.sax.SAXParseException; lineNumber: 15; columnNumber: 72; cvc-complex-type.2.4.c: 通配符的匹配很全面, 但无法找到元素 'context:component-scan' 的声明。rn at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198)rn at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:134)rn at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:437)rn at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:368)rn at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:325)rn at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(XMLSchemaValidator.java:458)rn at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(XMLSchemaValidator.java:3237)rn at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(XMLSchemaValidator.java:1917)rn at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.emptyElement(XMLSchemaValidator.java:766)rn at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:355)rn at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2770)rn at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)rn at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:117)rn at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)rn at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)rn at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)rn at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)rn at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:243)rn at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:347)rn at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:75)rn at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:388)rn ... 37 more

打成jar包就不能被sping的context:component-scan找到了吗?

01-03

有关sprigmvc的问题rnrn我有一个普通的controller,比如:rn[code=java]rn@Controller("test")rnpublic class Testrn @RequestMapping(value = "/aaa.bo", method = RequestMethod.GET)rn public String aaa(HttpServletRequest request) rn System.out.println("fdsfsd");rn return null;rn rnrn[/code]rn然后,在DispatcherServlet的xml配置文件中,rn定义一个scan,如下rn[code=text]rn rn rn rn[/code]rnrn问题来了。rnrn当我[color=#008000]在工程里的src存在这个Test.java文件,rn启动服务,然后在浏览器里输入XXXX/aaa.bo,rn可以正常执行到Test这个aaa方法[/color]rnrn但是,rn如果我[color=#FF0000]把这个Test.java生成class文件,然后再打成一个jar包,rn放在另一个工程的WEB-INFO\lib目录下[/color],rn当我启动另外的这个工程的时候,rn执行XXXX/aaa.bo的时候,就出现了下面的错误rn[color=#FF0000][b]WARN[org.springframework.web.servlet.PageNotFound:1108]No mapping found for HTTP request with URI [/XXXX/aaa.bo] in DispatcherServlet with name 'xxxDispatcher'[/b][/color]rnrn请问:rn如果控制器打成jar包就不能被spring扫描到了吗?rn按说如果放在classpath里,是可以被找到的,rn而且反射机制读取的注解也无所谓在不在jar包啊???rnrn那么,这个控制器就不能被打成jar包喽?rn打包以后发布给别的工程当作通用的处理也是不行的吧?rn还是我的方法有问题,缺少了什么步骤呢?rnrn我潜意识里感觉我好像问了一个傻问题,rn或者根本就是在什么地方不允许这么做,我没有意识到。。rn求拍醒rnrn谢谢

Spring component-scan 无法扫描jar中的annotation注解

10-20

错误代码如下,如果Jar未编译是可以通过的rn[code=Java]org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ESTMessage': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [est.session.service.IEstDwrReverse] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: rn at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:306)rn at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1118)rn at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)rn at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)rn at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)rn at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)rn at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)rn at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)rn at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:605)rn at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:926)rn at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:477)rn at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139)rn at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:83)[/code]rn网上都说导出的时候勾上那个add enxxxx的选项,我这个做了但是还有这个错,求高人指点

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试