以前學習Spring時,使用IOC,需要利用到xml配置文件進行組建的註冊和設定等等。同樣也可以使用註解的方式進行操作,下面是個人在學習註解開發過程中做的一些總結;
1、@Configuration:告訴Spring,當前class類是一個配置類,等同於以前的xml文件;在@Configuration裏面,其實也是一個@Component;要想被@Configuration註解,當前類不可以是final類型,不可以是匿名類;
2、@Bean:註冊一個組件;相當於以前在xml文件中的<bean/>標籤;
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
可以看到@Bean可以再METHOD(方法),ANNOCITION_TYPE上進行註解,@Bean有如下幾個屬性可以進行設置:
參數 | 默認值 | 概念 |
value |
默認爲方法名 | bean別名,和name相互依賴關聯的,value,name如果都使用的話值必須要一致 |
name | 默認方法名 | 相當於xml配置中<bean/>標籤的id |
autowire |
Autowire.NO,默認不開啓自動裝配 | |
initMethod |
-- | 初始化方法 |
destroyMethod |
-- | 註銷方法 |
3、@ComponentScan:指定包掃描策略,相當於xml配置文件中的<context:component-scan/>標籤,其中可以進行一些屬性設定,常用的屬性有以下幾種:
參數 | 默認值或者類型 | 概念 |
value |
string | 指定需要掃描的包路徑 |
excludeFilters | Filter [] | 按照一定策略,排除需要掃描的包 |
includeFilters |
Filter [] | 按照一定策略,只需要掃描指定的包,需要和useDefaultFilters=false搭配使用,要不然沒效果 |
useDefaultFilters |
true | 默認寶掃描策略 |
其中excludeFilter和includeFilter在使用是,需要使用到@Filter註解來指定策略,如下例子:
1、指定只掃描包含@Controller註解的bean
includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
},useDefaultFilters = false
2、指定只掃描不包含@Controller註解的bean
excludeFilters= {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
}
上面Filter的type可以有以下集中掃描策略:
FilterType.ANNOTATION | 按照註解規則,過濾被指定註解標記的類 |
FilterType.ASSIGNABLE_TYPE | 按照給定的類型 |
FilterType.ASPECTJ | ASPECTJ表達式 |
FilterType.REGEX | 正則表達式 |
FilterType.CUSTOM | 自定義規則 |
當然,@ComponentScan可以寫多個,同樣也可是使用@ComponentScans包含多個@ComponentScan;
@ComponentScans(value = {
@ComponentScan(value = "com.snail.tool.annocation",
excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
}
),
@ComponentScan(value = "com.snail.tool.annocation",
includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
}
,useDefaultFilters = false
)
})
做個測試,首先測試一下@Configuration和@Bean;定義一個bean類Student,在定義一個MyConfig的配置類,往容器中注入一個名爲stu的Student類型的bean,編寫測試類,看是否可以拿到;
1、student類
@Data
@ToString
public class Student {
private int age;
private String name;
public Student() {
}
public Student(int age, String name) {
this.age = age;
this.name = name;
}
}
----------------------------------------------------------------
2、Myconfig配置類
/**
* @Configuration 作用是:告訴spring,當前class文件爲一個配置類文件
*/
@Configuration
public class MyConfig {
/**
* @Bean 作用是:向容器中註冊一個bean對象,改對象的類型爲返回值類型,id爲方法名。
* 相當於配置文件中的bean標籤
*/
@Bean()
public Student student(){
return new Student(20,"idea");
}
}
------------------------------------------------------------------
3、測試類
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootAnnocationApplicationTests {
@Test
public void contextLoads() {
ApplicationContext alicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
Object student = alicationContext.getBean("stu");
System.out.println(student);
}
}
結果:
Student(age=20, name=idea)
測試二,測試excludeFilter:新建controller,service,dao,分別使用@Controller,@service,@Repository註解,首先掃描不包括controller的所有bean;
1、Myconfig類
@Configuration
@ComponentScan(value = "com.snail.tool.annocation",
excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
}
)
public class MyConfig {
}
------------------------------------------------------
2、測試類
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootAnnocationApplicationTests {
@Test
public void contextLoads1(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
}
結果:
可以看到,沒有controllrt。但是爲什麼會有myconfig?因爲@Configuration底層是使用@Component註解的;
測試三,測試includeFilter:掃描只包括controller的所有bean;
1、Myconfig類
@Configuration
@ComponentScan(value = "com.snail.tool.annocation",
includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
},useDefaultFilters = false
)
public class MyConfig {
}
------------------------------------------------------
2、測試類
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootAnnocationApplicationTests {
@Test
public void contextLoads1(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
}
結果:
上面便是自己總結的一部分只是內容,當初學的時候也是整個人都傻傻的,學就完事了。如有不對,還請指出,謝謝;