<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
之前,我們需要掃描工程下一些類上所標註的註解,這些常用註解有:
@Controller,@Service,@Component,@Repository
通過在Spring的組態檔中設定<context:component-scan>掃描對應包下掃描這些註解的方式:
<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>
建三個類,依次將
@Controller,@Repository,@Service,標註這些類:
圖1
現在通過使用註解@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); } }
測試,看是否掃描到這些註解所標註的類: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); } }
測試效果:除了Spring要自動載入的設定類以外也顯示了剛才新增的設定類:
圖2
為何會出現PersonConfig,因為@Configuration本 身就是@Component註解的:
圖3
如果需要指定設定類的掃描規則,@ComponentScan提供對應的掃描方式@Filter進行設定類的過濾:
// 掃描包的時候只規定掃描一些註解設定類。 Filter[] includeFilters() default {}; // 掃描包的時候可以排除一些註解設定類。 Filter[] excludeFilters() default {};
Filter其實也是一個註解,相當於@ComponentScan的子註解,可以看圖4:
圖4
Filter對應的過濾規則如下:
第一種:掃描包的時候只規定掃描一些註解設定類【includeFilters】。
使用這個includeFilters過濾規則,必須解除預設的過濾規則,
使用【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); } }
這樣就只會掃描用@Controller,標註的設定類交給Spring容器中了:
圖5
第二種:掃描包的時候可以排除一些註解設定類【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); } }
測試看一下發現圖2中的personController不會交給Spring容器去管理了:
圖7
上面的圖6展示出5種不同型別的過濾策略,上面介紹了註解型別(FilterType.ANNOTATION),還有四種:
重點看一下CUSTOM自定義掃描策略。
從原始碼看,自定義掃描註解型別需要實現TypeFilter介面,下面就寫一個實現類MyFilter.java:在實現類中可以自定義設定規則:
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 { // 檢視當前類的註解。 AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); // 檢視當前掃描類的資訊 ClassMetadata classMetadata = metadataReader.getClassMetadata(); // 獲取當前類資源 Resource resource = metadataReader.getResource(); String className = classMetadata.getClassName(); System.out.println("className===>" + className); // 只要類名包含er則註冊Spring容器 if(className.contains("er")) { return true; } return false; } }
測試:
PersonConfig 中進行掃描:
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:按照指定的型別去載入對應設定類:
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依然會載入出來(自行測試)。
ASPECTJ與REGEX基本不用,不用瞭解。
以上就是@ComponentScan的具體用法,該興趣的話可以看一下原始碼。
到此這篇關於詳解Spring系列之@ComponentScan自動掃描元件的文章就介紹到這了,更多相關Spring @ComponentScan內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45