spring註解注入:詳解

spring註解注入:<context:component-scan>詳解

更多9

spring從2.5版本開始支持註解注入,註解注入能夠省去不少的xml配置工做。因爲註解是寫入java代碼中的,因此註解注入會失去必定的靈活性,咱們要根據須要來選擇是否啓用註解注入。java

咱們首先看一個註解注入的實際例子,而後再詳細介紹context:component-scan的使用。正則表達式

若是你已經在用spring mvc的註解配置,那麼你必定已經在使用註解注入了,本文不會涉及到spring mvc,咱們用一個簡單的例子來講明問題。spring

本例中咱們會定義以下類:數據庫

  1. PersonService類,給上層提供Person相關操做
  2. PersonDao類,給PersonService類提供DAO方法
  3. Person類,定義Person相關屬性,是一個POJO
  4. App類,入口類,調用註解注入的PersonService類

PersonService類實現以下:express

package cn.outofmemory.spring; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class PersonService { @Autowired private PersonDao personDao; public Person getPerson(int id) { return personDao.selectPersonById(id); } }

在Service類上使用了@Service註解修飾,在它的私有字段PersonDao上面有@Autowired註解修飾。@Service告訴spring容器,這是一個Service類,默認狀況會自動加載它到spring容器裏。而@Autowired註解告訴spring,這個字段是須要自動注入的。swift

PersonDao類:mvc

package cn.outofmemory.spring; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Repository; @Scope("singleton") @Repository public class PersonDao { public Person selectPersonById(int id) { Person p = new Person(); p.setId(id); p.setName("Person name"); return p; } }

在PersonDao類上面有兩個註解,分別爲@Scope和@Repository,前者指定此spring bean的scope是單例,你也能夠根據須要將此bean指定爲prototype,@Repository註解指定此類是一個容器類,是DA層類的實現。這個類咱們只是簡單的定義了一個selectPersonById方法,該方法的實現也是一個假的實現,只是聲明瞭一個Person的新實例,而後設置了屬性,返回他,在實際應用中DA層的類確定是要從數據庫或者其餘存儲中取數據的。app

Person類:ui

package cn.outofmemory.spring; public class Person { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }

Person類是一個POJO。this

App類:

package cn.outofmemory.spring; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /**  * Hello spring! from outofmemory.cn  *  */ public class App  {     public static void main( String[] args )     {         ApplicationContext appContext = new ClassPathXmlApplicationContext("/spring.xml");         PersonService service = appContext.getBean(PersonService.class);         Person p = service.getPerson(1);         System.out.println(p.getName());     } }

在App類的main方法中,咱們初始化了ApplicationContext,而後從中獲得咱們註解注入的PersonService類,而後調用此對象的getPerson方法,並輸出返回結果的name屬性。

註解注入也必須在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="cn.outofmemory.spring" use-default-filters="false"> <context:include-filter type="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 Type Examples Expression Description
annotation org.example.SomeAnnotation 符合SomeAnnoation的target class
assignable org.example.SomeClass 指定class或interface的全名
aspectj org.example..*Service+ AspectJ語法
regex org\.example\.Default.* Regelar Expression
custom org.example.MyTypeFilter Spring3新增自訂Type,實做org.springframework.core.type.TypeFilter

在咱們的示例中,將filter的type設置成了正則表達式,regex,注意在正則裏面.表示全部字符,而\.才表示真正的.字符。咱們的正則表示以Dao或者Service結束的類。

咱們也可使用annotaion來限定,以下:

<?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="cn.outofmemory.spring" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>  <context:include-filter type="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-18 21:14:18 org.springframework.context.support.AbstractApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1cac6db: startup date [Sun May 18 21:14:18 CST 2014]; root of context hierarchy 2014-5-18 21:14:18 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [spring.xml] 2014-5-18 21:14:18 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons 信息: Pre-instantiating singletons in org.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 hierarchy Person name

前幾行都是spring輸出的一些調試信息,最後一行是咱們本身程序的輸出。

本文源碼下載:spring-DI-annotation.zip

相關文章
相關標籤/搜索