您好,登錄后才能下訂單哦!
這篇文章主要講解了“Spring之@ComponentScan自動(dòng)掃描組件怎么使用”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Spring之@ComponentScan自動(dòng)掃描組件怎么使用”吧!
之前,我們需要掃描工程下一些類上所標(biāo)注的注解,這些常用注解有:
@Controller,@Service,@Component,@Repository
通過在Spring的配置文件中配置<context:component-scan>掃描對(duì)應(yīng)包下掃描這些注解的方式:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 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-2.5.xsd"> <!--@Controller,@Service,@Component,@Repository--> <context:component-scan base-package="com.jektong.spring"/> </beans>
建三個(gè)類,依次將
@Controller,@Repository,@Service,標(biāo)注這些類:
圖1
現(xiàn)在通過使用注解@ComponentScan的方式來掃描所在包下面的這些類:之前定義的PersonConfig修改:
package com.jektong.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import com.jektong.spring.Person; @Configuration @ComponentScan("com.jektong") public class PersonConfig { @Bean("person01") public Person person() { return new Person("李四",21); } }
測(cè)試,看是否掃描到這些注解所標(biāo)注的類:PersonTest.java
@Test public void test02() { ApplicationContext ac = new AnnotationConfigApplicationContext(PersonConfig.class); Person bean = ac.getBean(Person.class); System.out.println(bean); String[] beanDefinitionNames = ac.getBeanDefinitionNames(); for (String string : beanDefinitionNames) { System.out.println(string); } }
測(cè)試效果:除了Spring要自動(dòng)加載的配置類以外也顯示了剛才添加的配置類:
圖2
為何會(huì)出現(xiàn)PersonConfig,因?yàn)锧Configuration本 身就是@Component注解的:
圖3
如果需要指定配置類的掃描規(guī)則,@ComponentScan提供對(duì)應(yīng)的掃描方式@Filter進(jìn)行配置類的過濾:
// 掃描包的時(shí)候只規(guī)定掃描一些注解配置類。 Filter[] includeFilters() default {}; // 掃描包的時(shí)候可以排除一些注解配置類。 Filter[] excludeFilters() default {};
Filter其實(shí)也是一個(gè)注解,相當(dāng)于@ComponentScan的子注解,可以看圖4:
圖4
Filter對(duì)應(yīng)的過濾規(guī)則如下:
第一種:掃描包的時(shí)候只規(guī)定掃描一些注解配置類【includeFilters】。
使用這個(gè)includeFilters過濾規(guī)則,必須解除默認(rèn)的過濾規(guī)則,
使用【useDefaultFilters = false】:
package com.jektong.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.stereotype.Controller; import com.jektong.spring.Person; @Configuration @ComponentScan(value = "com.jektong",includeFilters = { @Filter(type = FilterType.ANNOTATION,value= {Controller.class}) },useDefaultFilters = false ) public class PersonConfig { @Bean("person01") public Person person() { return new Person("李四",21); } }
這樣就只會(huì)掃描用@Controller,標(biāo)注的配置類交給Spring容器中了:
圖5
第二種:掃描包的時(shí)候可以排除一些注解配置類【excludeFilters】。
圖6
@Filter看上圖,有5種不同類型的過濾策略。拿第一種舉例,我們需要過濾使用@Controller注解的配置類:
package com.jektong.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.stereotype.Controller; import com.jektong.spring.Person; @Configuration @ComponentScan(value = "com.jektong",excludeFilters = { @Filter(type = FilterType.ANNOTATION,value= {Controller.class}) } ) public class PersonConfig { @Bean("person01") public Person person() { return new Person("李四",21); } }
測(cè)試看一下發(fā)現(xiàn)圖2中的personController不會(huì)交給Spring容器去管理了:
圖7
上面的圖6展示出5種不同類型的過濾策略,上面介紹了注解類型(FilterType.ANNOTATION),還有四種:
重點(diǎn)看一下CUSTOM自定義掃描策略。
從源碼看,自定義掃描注解類型需要實(shí)現(xiàn)TypeFilter接口,下面就寫一個(gè)實(shí)現(xiàn)類MyFilter.java:在實(shí)現(xiàn)類中可以自定義配置規(guī)則:
package com.jektong.config; import java.io.IOException; import org.springframework.core.io.Resource; import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.ClassMetadata; import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.core.type.filter.TypeFilter; public class MyFilter implements TypeFilter { @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { // 查看當(dāng)前類的注解。 AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); // 查看當(dāng)前掃描類的信息 ClassMetadata classMetadata = metadataReader.getClassMetadata(); // 獲取當(dāng)前類資源 Resource resource = metadataReader.getResource(); String className = classMetadata.getClassName(); System.out.println("className===>" + className); // 只要類名包含er則注冊(cè)Spring容器 if(className.contains("er")) { return true; } return false; } }
測(cè)試:
PersonConfig 中進(jìn)行掃描:
package com.jektong.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.stereotype.Controller; import com.jektong.service.PersonService; import com.jektong.spring.Person; @Configuration @ComponentScan(value = "com.jektong",includeFilters = { @Filter(type = FilterType.CUSTOM,value= {MyFilter.class}) },useDefaultFilters = false ) public class PersonConfig { @Bean("person01") public Person person() { return new Person("李四",21); } }
可以看出掃描出包下面的類只要帶“er”的全部掃描出來,并配置給Spring容器:
ASSIGNABLE_TYPE:按照指定的類型去加載對(duì)應(yīng)配置類:
package com.jektong.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.stereotype.Controller; import com.jektong.service.PersonService; import com.jektong.spring.Person; @Configuration @ComponentScan(value = "com.jektong",includeFilters = { @Filter(type = FilterType.ASSIGNABLE_TYPE,value= {PersonService.class}) },useDefaultFilters = false ) public class PersonConfig { @Bean("person01") public Person person() { return new Person("李四",21); } }
盡管我們將PersonService.java上的注解去掉,使用ASSIGNABLE_TYPE依然會(huì)加載出來(自行測(cè)試)。
ASPECTJ與REGEX基本不用,不用了解。
感謝各位的閱讀,以上就是“Spring之@ComponentScan自動(dòng)掃描組件怎么使用”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)Spring之@ComponentScan自動(dòng)掃描組件怎么使用這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。