2、Spring註解開發,第二天
阿新 • • 發佈:2019-10-03
一、TypeFilter指定過濾規則
最常用的兩個
FilterType.Annotation 按照註解
FilterType.ASSIGNABLE_TYPE 按照給定的型別
自定義規則
FilterType.Custom 自定義規則--實現TypeFilter介面[TypeFilter和FilterType有區別的]
1、FilterType.ASSIGNABLE_TYPE
package com.lee.config; import com.lee.bean.Person; import com.lee.service.BookService; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.stereotype.Controller; //@ComponentScan("com.lee")//自動掃描 value指定要掃描的包 @Configuration//告訴Spring這是一個配置類 //@ComponentScan(value="com.lee",excludeFilters = { // @ComponentScan.Filter(type=FilterType.ANNOTATION,value = Controller.class) //}) @ComponentScan(value = "com.lee",useDefaultFilters=false,includeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION,value = Controller.class), @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,value= BookService.class) }) //FilterType.ANNOTATION 按照註解 //FilterType.ASSIGNABLE_TYPE 按照給定的型別 //FilterType.CUSTOM 按照自定義 public class MainConfig { //Bean 給容器註冊一個bean,型別為返回值的型別,id預設使用方法名作為id //@Bean("名字")可以給bean修改名稱 @Bean public Person person(){ return new Person(2,"lee2","male2"); } }
結果
mainConfig
bookController
bookService
person
2、FilterType.Custom
#metadataReader the metadata reader for the target class
#metadataReaderFactory a factory for obtaining metadata readers for other classes (such as superclasses and interfaces)
MyTypeFilter.class
package com.lee.config; 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; import java.io.IOException; public class MyTypeFilter implements TypeFilter { /** * * @param metadataReader 讀取到當前正在掃描類的資訊 * @param metadataReaderFactory 一個工廠,可以獲取到任何類的資訊 */ @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { ClassMetadata classMetadata = metadataReader.getClassMetadata(); System.out.println("======>"+classMetadata.getClassName()); if(classMetadata.getClassName().contains("ao")){ System.out.println("---->"+classMetadata.getClassName()); return true; } return false; } }
MainConfig.class
package com.lee.config; import com.lee.bean.Person; import com.lee.service.BookService; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.stereotype.Controller; //@ComponentScan("com.lee")//自動掃描 value指定要掃描的包 @Configuration//告訴Spring這是一個配置類 //@ComponentScan(value="com.lee",excludeFilters = { // @ComponentScan.Filter(type=FilterType.ANNOTATION,value = Controller.class) //}) @ComponentScan(value = "com.lee",useDefaultFilters=false,includeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION,value = Controller.class), @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,value= BookService.class), @ComponentScan.Filter(type=FilterType.CUSTOM,value = MyTypeFilter.class) }) //FilterType.ANNOTATION 按照註解 //FilterType.ASSIGNABLE_TYPE 按照給定的型別 //FilterType.CUSTOM 按照自定義 public class MainConfig { //Bean 給容器註冊一個bean,型別為返回值的型別,id預設使用方法名作為id //@Bean("名字")可以給bean修改名稱 @Bean public Person person(){ return new Person(2,"lee2","male2"); } }
結果:
mainConfig
bookController
bookDao
bookService
person
二、Scope設定元件作用域
spring預設Bean都是單例項的
1、單例-SINGLETON
MainConfig2.class
package com.lee.config;
import com.lee.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@ComponentScan(value = "com.lee")//包掃描
@Configuration//這是個配置類
public class MainConfig2 {
@Bean
public Person person(){
return new Person(1,"張三","male");
}
}
MainTest.class
package com.lee;
import com.lee.bean.Person;
import com.lee.config.MainConfig;
import com.lee.config.MainConfig2;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainTest {
@Test
public void test01(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig2.class);
Person person1 = (Person) context.getBean("person");
Person person2 = (Person) context.getBean("person");
System.out.println("person1 == person2 : "+(person1==person2));
}
}
結果:
person1 == person2 : true
2、原型-PROTOTYPE
MainConfig2.class
package com.lee.config;
import com.lee.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@ComponentScan(value = "com.lee")//包掃描
@Configuration//這是個配置類
public class MainConfig2 {
@Scope(value = "prototype")
@Bean
public Person person(){
return new Person(1,"張三","male");
}
}
結果:
person1 == person2 : false
三、懶載入
單例項bean:預設在容器啟動的時候建立物件
懶載入:容器啟動不建立物件,等第一次呼叫的時候才建立物件
1、預設
MainConfig2.class
package com.lee.config;
import com.lee.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@ComponentScan(value = "com.lee")//包掃描
@Configuration//這是個配置類
public class MainConfig2 {
@Scope(value = "prototype")
@Bean
public Person person(){
return new Person(1,"張三","male");
}
}
2、懶載入 lazy
MainConfig2.class
package com.lee.config;
import com.lee.bean.Person;
import org.springframework.context.annotation.*;
@ComponentScan(value = "com.lee")//包掃描
@Configuration//這是個配置類
public class MainConfig2 {
@Lazy//懶載入
@Scope(value = "prototype")
@Bean
public Person person(){
return new Person(1,"張三","male");
}
}
三、Conditional按條件註冊bean
按照一定的條件進行判斷,滿足條件給容器中註冊bean
WindowsCondition.class
package com.lee.conditions;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
if(property.contains("Window")){
return true;
}
return false;
}
}
LinuxCondition.class
package com.lee.conditions;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
if(property.contains("linux")){
return true;
}
return false;
}
}
MainConfig2.class
package com.lee.config;
import com.lee.bean.Person;
import com.lee.conditions.LinuxCondition;
import com.lee.conditions.WindowsCondition;
import org.springframework.context.annotation.*;
@ComponentScan(value = "com.lee")//包掃描
@Configuration//這是個配置類
public class MainConfig2 {
// @Lazy//懶載入
// @Scope(value = "prototype")
@Bean
public Person person(){
return new Person(1,"張三","male");
}
@Conditional({WindowsCondition.class})
@Bean("bill")
public Person person01(){
return new Person(2,"bill Gates","male");
}
@Conditional(LinuxCondition.class)
@Bean("linus")
public Person person02(){
return new Person(3,"linus","male");
}
}
MainTest.class
public class MainTest {
@Test
public void test02(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig2.class);
ConfigurableEnvironment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
System.out.println("===>"+property);
String[] beanNamesForType = context.getBeanNamesForType(Person.class);
for(String bean : beanNamesForType){
System.out.println(bean);
}
}
}
結果:
===>Windows 10
person
bill
在Run/Debug Configurations中加入環境變數
-Dos.name=linux
結果:
===>Linux
pe