目錄:一、TypeFilter指定過濾規則 二、Scope設置組件做用域 三、懶加載Lazy 四、Conditional按條件註冊beanjava
最經常使用的兩個 FilterType.Annotation 按照註解 FilterType.ASSIGNABLE_TYPE 按照給定的類型 自定義規則 FilterType.Custom 自定義規則--實現TypeFilter接口[TypeFilter和FilterType有區別的]
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"); } }
結果linux
mainConfig bookController bookService person
#metadataReader the metadata reader for the target class #metadataReaderFactory a factory for obtaining metadata readers for other classes (such as superclasses and interfaces)
MyTypeFilter.classspring
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.classide
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"); } }
結果:prototype
mainConfig bookController bookDao bookService person
spring默認Bean都是單實例的ssr
MainConfig2.classcode
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.classxml
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
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:默認在容器啓動的時候建立對象
懶加載:容器啓動不建立對象,等第一次調用的時候才建立對象
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"); } }
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"); } }
按照必定的條件進行判斷,知足條件給容器中註冊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 person linus
@Conditional不只能夠標註在方法method上,也能夠標註在類class上,這個類中全部bean註冊才能被生效