@Configuration注解告诉Spring这是一个配置类linux
@Bean注解是给容器中注册一个Bean,类型是返回值的类型,id默认是方法名做为idspring
@Bean("person") public Person person2(){ System.out.println("create a new bean of person"); return new Person(); }
@ComponentScan(value = "com.eric",excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class})windows
@ComponentScan 的属性数组
/** * Description: spring-parent * 配置类==配置文件 * * @author caoqianqian * @date 2021/2/14 */ @Configuration //告诉Spring这是一个配置类 @ComponentScan(value = "com.eric",excludeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class}) }) public class MainConfig { //给容器中注册一个Bean,类型是返回值的类型,id默认是方法名做为id @Bean public Person person(){ return new Person("testName",20); } }
经过@Scope注解来制定该bean的做用范围,也能够说是调整做用域,ioc容器中加载的组件默认是单实例的。session
做用域范围即value的可取值范围ide
//经过@Scope注解来制定该bean的做用范围,也能够说是调整做用域 @Scope("singleton") @Bean("person") public Person person() { System.out.println("I'm creating an instance Person"); return new Person("Person", 28); }
单实例bean:默认在容器启动的时候建立对象。
懒加载:容器启动不建立对象,第一次使用(获取)bean时建立对象,并初始化。测试
单实例bean加上懒加载的注解以后容器启动时不建立对象,第一次使用时才会去建立对象并初始化。prototype
@Bean("person") @Lazy public Person person2(){ System.out.println("create a new bean of person"); return new Person(); }
@Conditional按照必定的条件进行判断,知足条件给容器中注册beancode
标在方法上,表示这个方法知足必定条件才会生效。component
标在类上,类中组件统一设置,表示知足当前条件,这个类中配置的全部bean注册才会生效
判断是不是Linux系统
public class LinuxCondition implements Condition { /** *判断是不是Linux系统 * @param conditionContext 判断条件能使用的上下文(环境) * @param annotatedTypeMetadata 当前标注注解的注释信息 * @return */ @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { //能获取到ioc使用的beanFactory ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory(); //获取类加载器 ClassLoader classLoader = conditionContext.getClassLoader(); //获取当前环境信息 Environment environment = conditionContext.getEnvironment(); //获取bean定义的注册类 BeanDefinitionRegistry registry = conditionContext.getRegistry(); //判断容器中bean的注册状况 boolean definition = registry.containsBeanDefinition("person"); RootBeanDefinition beanDefinition = new RootBeanDefinition(Person.class); //给容器中注册bean registry.registerBeanDefinition("person2",beanDefinition); String property = environment.getProperty("os.name"); if(property.contains("linux")){ return true; } return false; } }
判断是不是Windows系统
public class WindowsCondition implements Condition { @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { Environment environment = conditionContext.getEnvironment(); String osName = environment.getProperty("os.name"); if (osName.contains("Windows")){ return true; } return false; } }
配置类
@Configuration public class MainConfig2 { /** *Conditional({Condition}):按照必定的条件进行判断,知足条件给容器中注册bean * 若是系统是windows,给容器中注册("bill") * 若是系统是linux,给容器中注册("linus") * @return */ @Conditional({WindowsCondition.class}) @Bean("bill") public Person person(){ return new Person("Bill Gates",62); } @Conditional({LinuxCondition.class}) @Bean("linus") public Person person2(){ return new Person("linus",42); } @Bean public ColorFactoryBean colorFactoryBean(){ return new ColorFactoryBean(); } }
测试方法
@Test public void testCondition() { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MainConfig2.class); ConfigurableEnvironment environment = ac.getEnvironment(); String[] beanNamesForType = ac.getBeanNamesForType(Person.class); //动态获取环境变量的值:windows 7 String property = environment.getProperty("os.name"); System.out.println(property); for (String p:beanNamesForType) { System.out.println(p); } }
运行结果以下,Windows 7的系统因此bill注册了进来
Windows 7 bill person2
快速导入组件,id默认是组件的全类名
配置类上加了@Import注解
@Configuration @Import({Color.class, Dog.class}) public class MainConfig2 { /** *Conditional({Condition}):按照必定的条件进行判断,知足条件给容器中注册bean * 若是系统是windows,给容器中注册("bill") * 若是系统是linux,给容器中注册("linus") * @return */ @Conditional({WindowsCondition.class}) @Bean("bill") public Person person(){ return new Person("Bill Gates",62); } @Conditional({LinuxCondition.class}) @Bean("linus") public Person person2(){ return new Person("linus",22); } }
测试方法
@Test public void testImport() { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MainConfig2.class); String[] beanNamesForType = ac.getBeanDefinitionNames(); for (String p:beanNamesForType) { System.out.println(p); } }
运行结果:除了内部的bean,Color和Dog也被注册进来了
org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory mainConfig2 com.eric.bean.Color com.eric.bean.Dog bill person2
//自定义逻辑返回须要导入的组件 public class MyImportSelector implements ImportSelector { //返回值就是导入到容器中的组件的全类名 //AnnotationMetadata 当前标注@Import注解类的全部注解信息 @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { Set<String> annotationTypes = annotationMetadata.getAnnotationTypes(); for(String str : annotationTypes){ System.out.println("===="+str); } return new String[]{"com.eric.bean.Blue","com.eric.bean.Red"}; } }
@Import注解加上自定义的组件MyImportSelector
@Configuration @Import({Color.class, Dog.class,MyImportSelector.class}) public class MainConfig2 { /** *Conditional({Condition}):按照必定的条件进行判断,知足条件给容器中注册bean * 若是系统是windows,给容器中注册("bill") * 若是系统是linux,给容器中注册("linus") * @return */ @Conditional({WindowsCondition.class}) @Bean("bill") public Person person(){ return new Person("Bill Gates",62); } @Conditional({LinuxCondition.class}) @Bean("linus") public Person person2(){ return new Person("linus",22); } }
测试方法
@Test public void testImport() { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MainConfig2.class); String[] beanNamesForType = ac.getBeanDefinitionNames(); for (String p:beanNamesForType) { System.out.println(p); } }
运行结果:Blue Red 都被注册进来了
====org.springframework.context.annotation.Configuration ====org.springframework.context.annotation.Import org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory mainConfig2 com.eric.bean.Color com.eric.bean.Dog com.eric.bean.Blue com.eric.bean.Red bill person2
手动注册bean到容器中
//要被注册的bean public class Rainbow { }
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { /** * * @param importingClassMetadata 当前类的注解信息 * @param registry BeanDefinition注册类 * 把全部须要添加到容器中的bean,调用 * BeanDefinitionRegistry.registerBeanDefinition手工注册进来 */ @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { boolean blueDefinition = registry.containsBeanDefinition("com.eric.bean.Blue"); if (blueDefinition){ //指定bean的定义信息 RootBeanDefinition beanDefinition = new RootBeanDefinition(Rainbow.class); //注册一个bean,指定bean名 registry.registerBeanDefinition("rainbow", beanDefinition); } } }
配置类:@Import加入了中MyImportBeanDefinitionRegistrar
@Configuration @Import({Color.class, Blue.class,MyImportBeanDefinitionRegistrar.class}) public class MainConfig2 { }
测试方法:
@Test public void testImport() { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MainConfig2.class); String[] beanNamesForType = ac.getBeanDefinitionNames(); for (String p:beanNamesForType) { System.out.println(p); } }
运行结果:逻辑判断Blue存在因此rainbow被注册了进来
mainConfig2 com.eric.bean.Blue bill person2 rainbow
使用spring提供的FactoryBean(工厂Bean)
建立一个ColorFactoryBean实现FactoryBean接口:
//建立一个Spring定义的FactoryBean public class ColorFactoryBean implements FactoryBean<Color> { /** * 返回一个Color对象,这个对象会添加到容器中 * @return * @throws Exception */ @Override public Color getObject() throws Exception { System.out.println("ColorFactoryBean=========getObject====="); return new Color(); } /** * 返回的bean类型 * @return */ @Override public Class<Color> getObjectType() { return Color.class; } /** * 是否单例 * 返回true表明是单实例,在容器中保存一份 * false是多实例,每次获取都会建立一个新的bean * @return */ @Override public boolean isSingleton() { return true; } }
配置类里注册该工厂bean
@Configuration public class MainConfig2 { @Bean public ColorFactoryBean colorFactoryBean(){ return new ColorFactoryBean(); } }
测试方法:
@Test public void testFactoryBean() { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MainConfig2.class); //工厂bean获取的是调用getObject()方法建立的对象 Object bean1 = ac.getBean("colorFactoryBean"); Object bean2 = ac.getBean("colorFactoryBean"); System.out.println("bean的类型:"+bean1.getClass()); //单实例返回true 多实例返回false System.out.println(bean1 == bean2); //默认获取到的是工厂bean调用getObejct建立的对象 //要获取工厂bean自己,咱们须要给id前面加一个&标识 Object bean3 = ac.getBean("&colorFactoryBean"); System.out.println("bean3的类型:"+bean3.getClass()); }
运行结果: 单实例获取到的是相同的bean,加&以后获取到的bean为ColorFactoryBean
ColorFactoryBean=========getObject===== bean的类型:class com.eric.bean.Color true bean3的类型:class com.eric.condition.ColorFactoryBean
给容器中注册组件:
ok,组件注册完结,撒花。