spring注解注入:<context:component-scan>详解

上一篇 / 下一篇  2017-08-07 17:53:43 / 个人分类:Spring

转载自http://outofmemory.cn/java/spring/spring-DI-with-annotation-context-component-scan

spring从2.5版本开始支持注解注入,注解注入可以省去很多的xml配置工作。由于注解是写入java代码中的,所以注解注入会失去一定的灵活性,我们要根据需要来选择是否启用注解注入。

我们首先看一个注解注入的实际例子,然后再详细介绍context:component-scan的使用。

如果你已经在用spring mvc的注解配置,那么你一定已经在使用注解注入了,本文不会涉及到spring mvc,我们用一个简单的例子来说明问题。

本例中我们会定义如下类:

  1. PersonService类,给上层提供Person相关操作
  2. PersonDao类,给PersonService类提供DAO方法
  3. Person类,定义Person相关属性,是一个POJO
  4. App类,入口类,调用注解注入的PersonService类

PersonService类实现如下:

packagecn.outofmemory.spring;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;@ServicepublicclassPersonService{@AutowiredprivatePersonDaopersonDao;publicPersongetPerson(intid){returnpersonDao.selectPersonById(id);}}

在Service类上使用了@Service注解修饰,在它的私有字段PersonDao上面有@Autowired注解修饰。@Service告诉spring容器,这是一个Service类,默认情况会自动加载它到spring容器里。而@Autowired注解告诉spring,这个字段是需要自动注入的。

PersonDao类:

packagecn.outofmemory.spring;importorg.springframework.context.annotation.Scope;importorg.springframework.stereotype.Repository;@Scope("singleton")@RepositorypublicclassPersonDao{publicPersonselectPersonById(intid){Personp=newPerson();p.setId(id);p.setName("Person name");returnp;}}

在PersonDao类上面有两个注解,分别为@Scope和@Repository,前者指定此spring bean的scope是单例,你也可以根据需要将此bean指定为prototype,@Repository注解指定此类是一个容器类,是DA层类的实现。这个类我们只是简单的定义了一个selectPersonById方法,该方法的实现也是一个假的实现,只是声明了一个Person的新实例,然后设置了属性,返回他,在实际应用中DA层的类肯定是要从数据库或者其他存储中取数据的。

Person类:

packagecn.outofmemory.spring;publicclassPerson{privateintid;privateStringname;publicintgetId(){returnid;}publicvoidsetId(intid){this.id=id;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}}

Person类是一个POJO。

App类:

packagecn.outofmemory.spring;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext;/**
 * Hello spring! from outofmemory.cn
 *
 */publicclassApp {   publicstaticvoidmain(String[]args)   {       ApplicationContextappContext=newClassPathXmlApplicationContext("/spring.xml");       PersonServiceservice=appContext.getBean(PersonService.class);       Personp=service.getPerson(1);       System.out.println(p.getName());   }}

在App类的main方法中,我们初始化**plicationContext,然后从中得到我们注解注入的PersonService类,然后调用此对象的getPerson方法,并输出返回结果的name属性。

注解注入也必须在spring的配置文件中做配置,我们看下spring.xml文件的内容:

<?xml version="1.0"encoding="UTF-8"?><beansxmlns="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-scanbase-package="cn.outofmemory.spring"use-default-filters="false"><context:include-filtertype="regex"expression="cn\.outofmemory\.spring\.[^.]+(Dao|Service)"/></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属性设置成了false。

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,注意在正则里面.表示所有字符,而\.才表示真正的.字符。我们的正则表示以Dao或者Service结束的类。

我们也可以使用annotaion来限定,如下:

<?xml version="1.0"encoding="UTF-8"?><beansxmlns="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-scanbase-package="cn.outofmemory.spring"use-default-filters="false"><context:include-filtertype="annotation"expression="org.springframework.stereotype.Repository"/> <context:include-filtertype="annotation"expression="org.springframework.stereotype.Service"/> </context:component-scan></beans>

 这里我们指定的include-filter的type是annotation,expression则是注解类的全名。

另外context:conponent-scan节点还有<context:exclude-filter>可以用来指定要排除的类,其用法和include-filter一致。

最后我们要看下输出的结果了,运行App类,输出:

2014-5-1821:14:18org.springframework.context.support.AbstractApplicationContextprepareRefresh信息:Refreshingorg.springframework.context.support.ClassPathXmlApplicationContext@1cac6db:startup date[SunMay1821:14:18CST2014];root of context hierarchy2014-5-1821:14:18org.springframework.beans.factory.xml.XmlBeanDefinitionReaderloadBeanDefinitions信息:LoadingXML bean definitionsfromclasspath resource[spring.xml]2014-5-1821:14:18org.springframework.beans.factory.support.DefaultListableBeanFactorypreInstantiateSingletons信息:Pre-instantiating singletonsinorg.springframework.beans.factory.support.DefaultListableBeanFactory@1fcf790:defining beans[personDao,personService,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor];root of factory hierarchyPersonname

前几行都是spring输出的一些调试信息,最后一行是我们自己程序的输出。

本文源码下载:spring-DI-annotation.zip



TAG:

 

评分:0

我来说两句

Open Toolbar