一般你能夠在xml配置文件中,聲明一個bean或者component,而後Spring容器會檢查和註冊你的bean或component。實際上,Spring支持自動掃描bean或component,你能夠沒必要再在xml文件中繁瑣的聲明bean,Spring會自動掃描、檢查你指定包的bean或component。java
如下列舉一個簡單的Spring Project,包含了Customer、Service、DAO層,讓咱們來看一下手動配置和自動掃描的不一樣。spring
先看一下正常手動配置一個beanexpress
DAO層,CustomerDAO.java以下:ide
package com.lei.customer.dao; public class CustomerDAO { @Override public String toString() { return "Hello , This is CustomerDAO"; } }
Service層,CustomerService.java以下:this
package com.lei.customer.services; import com.lei.customer.dao.CustomerDAO; public class CustomerService { CustomerDAO customerDAO; public void setCustomerDAO(CustomerDAO customerDAO) { this.customerDAO = customerDAO; } @Override public String toString() { return "CustomerService [customerDAO=" + customerDAO + "]"; } }
配置文件,Spring-Customer.xml文件以下:code
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="customerService" class="com.lei.customer.services.CustomerService"> <property name="customerDAO" ref="customerDAO" /> </bean> <bean id="customerDAO" class="com.lei.customer.dao.CustomerDAO" /> </beans>
運行以下代碼,App.java以下:component
package com.lei.common; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.lei.customer.services.CustomerService; public class App { public static void main( String[] args ) { ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"Spring-Customer.xml"}); CustomerService cust = (CustomerService)context.getBean("customerService"); System.out.println(cust); } }
輸出結果:CustomerService [customerDAO=Hello , This is CustomerDAO]
如今,看一下怎樣運用Spring的自動掃描。xml
用註釋@Component來表示這個Class是一個自動掃描組件。blog
Customer.java以下:get
package com.lei.customer.dao; import org.springframework.stereotype.Component; @Component public class CustomerDAO { @Override public String toString() { return "Hello , This is CustomerDAO"; } }
CustomerService.java以下:
package com.lei.customer.services; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.lei.customer.dao.CustomerDAO; @Component public class CustomerService { @Autowired CustomerDAO customerDAO; @Override public String toString() { return "CustomerService [customerDAO=" + customerDAO + "]"; } }
配置文件Spring-customer.xml以下
<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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <context:component-scan base-package="com.lei.customer" /> </beans>
注意:
以上xml文件中,加入了「context:component-scan」標籤,這樣就將Spring的自動掃描特性引入,base-package表示你的組件的存放位置,Spring將掃描對應文件夾下的bean(用@Component註釋過的),將這些bean註冊到容器中。
最後運行結果與手動配置的結果一致。
上例中,默認狀況下,Spring將把組件Class的第一個字母變成小寫,來做爲自動掃描組件的名稱,例如將「CustomerService」轉變爲「customerservice」,你能夠用「customerService」這個名字調用組件,以下:
CustomerService cust = (CustomerService)context.getBean("customerService");
你能夠像下邊這樣,建立自定義的組件名稱:
@Service("AAA") public class CustomerService ...
如今,能夠調用本身定義的組件了,以下:
CustomerService cust = (CustomerService)context.getBean("AAA");
有4種註釋類型,分別是:
@Component ——表示一個自動掃描component
@Repository ——表示持久化層的DAO component
@Service ——表示業務邏輯層的Service component
@Controller ——表示表示層的Controller component
以上4種,在應用時,咱們應該用哪種?讓咱們先看一下@Repository、@Service、@Controller的源代碼
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Repository { String value() default ""; }
你還能夠看一下@Service、@Controller的源代碼,發現它們都用@Component註釋過了,因此,在項目中,咱們能夠將全部自動掃描組件都用@Component註釋,Spring將會掃描全部用@Component註釋過得組件。
實際上,@Repository、@Service、@Controller三種註釋是爲了增強代碼的閱讀性而創造的,你能夠在不一樣的應用層中,用不一樣的註釋,就像下邊這樣。
DAO層:
package com.lei.customer.dao; import org.springframework.stereotype.Repository; @Repository public class CustomerDAO { @Override public String toString() { return "Hello , This is CustomerDAO"; } }
Service層:
package com.lei.customer.services; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.lei.customer.dao.CustomerDAO; @Service public class CustomerService { @Autowired CustomerDAO customerDAO; @Override public String toString() { return "CustomerService [customerDAO=" + customerDAO + "]"; } }
下例演示了用「filter」自動掃描註冊組件,這些組件只要匹配定義的「regex」的命名規則,Clasee前就不須要用@Component進行註釋。
DAO層,CustomerDAO.java以下:
package com.lei.customer.dao; public class CustomerDAO { @Override public String toString() { return "Hello , This is CustomerDAO"; } }
Service層,CustomerService.java以下:
package com.lei.customer.services; import org.springframework.beans.factory.annotation.Autowired; import com.lei.customer.dao.CustomerDAO; public class CustomerService { @Autowired CustomerDAO customerDAO; @Override public String toString() { return "CustomerService [customerDAO=" + customerDAO + "]"; } }
Spring Filtering,xml配置以下:
<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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <context:component-scan base-package="com.lei" > <context:include-filter type="regex" expression="com.lei.customer.dao.*DAO.*" /> <context:include-filter type="regex" expression="com.lei.customer.services.*Service.*" /> </context:component-scan> </beans>
注意:
以上xml文件中,全部文件名字,只要包含DAO和Service(*DAO.*,*Service.*)關鍵字的,都將被檢查註冊到Spring容器中。
運行如下代碼:
package com.lei.common; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.lei.customer.services.CustomerService; public class App { public static void main( String[] args ) { ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"Spring-AutoScan.xml"}); CustomerService cust = (CustomerService)context.getBean("customerService"); System.out.println(cust); } }
運行結果:CustomerService [customerDAO=Hello , This is CustomerDAO]
你也能夠用exclude,制定組件避免被Spring發現並被註冊到容器中。
如下配置排除用@Service註釋過的組件
<context:component-scan base-package="com.lei.customer" > <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" /> </context:component-scan>
如下配置排除包含「DAO」關鍵字的組件
<context:component-scan base-package="com.lei" > <context:exclude-filter type="regex" expression="com.lei.customer.dao.*DAO.*" /> </context:component-scan>