目录:一、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注册才能被生效