今天主要從如下幾個方面來介紹一下@ComponentScan註解:web
@ComponentScan註解是什麼正則表達式
@ComponentScan註解的詳細使用spring
1,@ComponentScan註解是什麼數組
其實很簡單,@ComponentScan主要就是定義掃描的路徑從中找出標識了須要裝配的類自動裝配到spring的bean容器中app
2,@ComponentScan註解的詳細使用ide
作過web開發的同窗必定都有用過@Controller,@Service,@Repository註解,查看其源碼你會發現,他們中有一個共同的註解@Component,沒錯@ComponentScan註解默認就會裝配標識了@Controller,@Service,@Repository,@Component註解的類到spring容器中,好下面我們就先來簡單演示一下這個例子測試
在包com.zhang.controller下新建一個UserController帶@Controller註解以下:this
package com.zhang.controller;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
}
在包com.zhang.service下新建一個UserService帶@Service註解以下:spa
package com.zhang.service;
import org.springframework.stereotype.Service;
@Service
public class UserService {
}
在包com.zhang.dao下新建一個UserDao帶@Repository註解以下:3d
package com.zhang.dao;
import org.springframework.stereotype.Repository;
@Repository
public class UserDao {
}
新建一個配置類以下:
/**
* 主配置類 包掃描com.zhang
*
* @author zhangqh
* @date 2018年5月12日
*/
@ComponentScan(value="com.zhang")
@Configuration
public class MainScanConfig {
}
新建測試方法以下:
AnnotationConfigApplicationContext applicationContext2 = new AnnotationConfigApplicationContext(MainScanConfig.class);
String[] definitionNames = applicationContext2.getBeanDefinitionNames();
for (String name : definitionNames) {
System.out.println(name);
}
運行結果以下:
mainScanConfig
userController
userDao
userService
怎麼樣,包掃描的方式比之前介紹的經過@Bean註解的方式是否是方便不少,這也就是爲何web開發的同窗常常使用此方式的緣由了
上面只是簡單的介紹了@ComponentScan註解檢測包含指定註解的自動裝配,接下來讓咱們來看看@ComponentScan註解的更加詳細的配置,在演示詳細的配置以前,讓咱們先看看@ComponentScan的源代碼以下:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
/**
* 對應的包掃描路徑 能夠是單個路徑,也能夠是掃描的路徑數組
* @return
*/
@AliasFor("basePackages")
String[] value() default {};
/**
* 和value同樣是對應的包掃描路徑 能夠是單個路徑,也能夠是掃描的路徑數組
* @return
*/
@AliasFor("value")
String[] basePackages() default {};
/**
* 指定具體的掃描的類
* @return
*/
Class<?>[] basePackageClasses() default {};
/**
* 對應的bean名稱的生成器 默認的是BeanNameGenerator
* @return
*/
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
/**
* 處理檢測到的bean的scope範圍
*/
Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
/**
* 是否爲檢測到的組件生成代理
* Indicates whether proxies should be generated for detected components, which may be
* necessary when using scopes in a proxy-style fashion.
* <p>The default is defer to the default behavior of the component scanner used to
* execute the actual scan.
* <p>Note that setting this attribute overrides any value set for {@link #scopeResolver}.
* @see ClassPathBeanDefinitionScanner#setScopedProxyMode(ScopedProxyMode)
*/
ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
/**
* 控制符合組件檢測條件的類文件 默認是包掃描下的 **/*.class
* @return
*/
String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;
/**
* 是否對帶有@Component @Repository @Service @Controller註解的類開啓檢測,默認是開啓的
* @return
*/
boolean useDefaultFilters() default true;
/**
* 指定某些定義Filter知足條件的組件 FilterType有5種類型如:
* ANNOTATION, 註解類型 默認
ASSIGNABLE_TYPE,指定固定類
ASPECTJ, ASPECTJ類型
REGEX,正則表達式
CUSTOM,自定義類型
* @return
*/
Filter[] includeFilters() default {};
/**
* 排除某些過來器掃描到的類
* @return
*/
Filter[] excludeFilters() default {};
/**
* 掃描到的類是都開啓懶加載 ,默認是不開啓的
* @return
*/
boolean lazyInit() default false;
}
a,演示basePackageClasses參數,如咱們把配置文件改爲以下:
@ComponentScan(value="com.zhang.dao",useDefaultFilters=true,basePackageClasses=UserService.class)
@Configuration
public class MainScanConfig {
}
測試結果以下:
mainScanConfig
userDao
userService
只有userDao外加basePackageClasses指定的userService加入到了spring容器中
b,演示includeFilters參數的使用以下:
在com.zhang.service包下新建一個UserService2類以下:注意沒有帶@Service註解
package com.zhang.service;
public class UserService2 {
}
配置類改爲:
@ComponentScan(value="com.zhang",useDefaultFilters=true,
includeFilters={
@Filter(type=FilterType.ANNOTATION,classes={Controller.class}),
@Filter(type=FilterType.ASSIGNABLE_TYPE,classes={UserService2.class})
})
@Configuration
public class MainScanConfig {
}
運行結果以下:
mainScanConfig
userController
userDao
userService
userService2
userService2一樣被加入到了spring容器
新增一個自定義的實現了TypeFilter的MyTypeFilter類以下:
/**
* 自定義過濾
*
* @author zhangqh
* @date 2018年5月12日
*/
public class MyTypeFilter implements TypeFilter {
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);
// 檢測名字包含Service的bean
if(className.contains("Service")){
return true;
}
return false;
}
}
修改主配置以下:
@ComponentScan(value="com.zhang",useDefaultFilters=true,
includeFilters={
@Filter(type=FilterType.ANNOTATION,classes={Controller.class}),
@Filter(type=FilterType.CUSTOM,classes={MyTypeFilter.class})
})
@Configuration
public class MainScanConfig {
}
運行結果以下:
mainScanConfig
userController
userDao
userService
userService2
能夠發現一樣userService2被加入到了spring容器中
好了includeFilters參數就演示到這,另一個參數excludeFilters和includeFilters用戶一摸同樣,只是他是過濾出不加入spring容器中,感興趣的同窗能夠本身試試,我這邊就不演示了
總結一下@ComponentScan的經常使用方式以下
自定掃描路徑下邊帶有@Controller,@Service,@Repository,@Component註解加入spring容器
經過includeFilters加入掃描路徑下沒有以上註解的類加入spring容器
經過excludeFilters過濾出不用加入spring容器的類
自定義增長了@Component註解的註解方式
最後一種方式這邊沒有演示,算留給你們的一個小問題吧,感興趣的同窗本身實現下,有疑問也歡迎留言
以上是今天文章的全部內容,歡迎你們吐槽
推薦閱讀
更多優質文章請關注如下公衆號查閱: