一 @Import导入组件,id默认是组件的全类名

1 //类中组件统一设置。满足当前条件,这个类中配置的所有bean注册才能生效;
 2 @Conditional({WindowsCondition.class})
 3 @Configuration
 4 @Import({Color.class,Red.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
 5 //@Import导入组件,id默认是组件的全类名
 6 public class MainConfig2 {
 7     
 8     //默认是单实例的
 9     /**
10      * ConfigurableBeanFactory#SCOPE_PROTOTYPE    
11      * @see ConfigurableBeanFactory#SCOPE_SINGLETON  
12      * @see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST  request
13      * @see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION  sesssion
14      * @return\
15      * @Scope:调整作用域
16      * prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。
17      *                  每次获取的时候才会调用方法创建对象;
18      * singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。
19      *          以后每次获取就是直接从容器(map.get())中拿,
20      * request:同一次请求创建一个实例
21      * session:同一个session创建一个实例
22      * 
23      * 懒加载:
24      *      单实例bean:默认在容器启动的时候创建对象;
25      *      懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;
26      * 
27      */
28 //  @Scope("prototype")
29     @Lazy
30     @Bean("person")
31     public Person person(){
32         System.out.println("给容器中添加Person....");
33         return new Person("张三", 25);
34     }
35     
36     /**
37      * @Conditional({Condition}) : 按照一定的条件进行判断,满足条件给容器中注册bean
38      * 
39      * 如果系统是windows,给容器中注册("bill")
40      * 如果是linux系统,给容器中注册("linus")
41      */
42     
43     @Bean("bill")
44     public Person person01(){
45         return new Person("Bill Gates",62);
46     }
47     
48     @Conditional(LinuxCondition.class)
49     @Bean("linus")
50     public Person person02(){
51         return new Person("linus", 48);
52     }
53     
54     /**
55      * 给容器中注册组件;
56      * 1)、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)[自己写的类]
57      * 2)、@Bean[导入的第三方包里面的组件]
58      * 3)、@Import[快速给容器中导入一个组件]
59      *      1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名
60      *      2)、ImportSelector:返回需要导入的组件的全类名数组;
61      *      3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中
62      * 4)、使用Spring提供的 FactoryBean(工厂Bean);
63      *      1)、默认获取到的是工厂bean调用getObject创建的对象
64      *      2)、要获取工厂Bean本身,我们需要给id前面加一个&
65      *          &colorFactoryBean
66      */
67     @Bean
68     public ColorFactoryBean colorFactoryBean(){
69         return new ColorFactoryBean();
70     }

二 实现Condition进行注入

1 Springboot有大量的@ConditionXXXX注解
 2 
 3 public class LinuxCondition implements Condition {
 4 
 5     /**
 6      * ConditionContext:判断条件能使用的上下文(环境)
 7      * AnnotatedTypeMetadata:注释信息
 8      */
 9     public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
10         // TODO是否linux系统
11         //1、能获取到ioc使用的beanfactory
12         ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
13         //2、获取类加载器
14         ClassLoader classLoader = context.getClassLoader();
15         //3、获取当前环境信息
16         Environment environment = context.getEnvironment();
17         //4、获取到bean定义的注册类
18         BeanDefinitionRegistry registry = context.getRegistry();
19 
20         String property = environment.getProperty("os.name");
21 
22         //可以判断容器中的bean注册情况,也可以给容器中注册bean
23         boolean definition = registry.containsBeanDefinition("person");
24         if(property.contains("linux")){
25             return true;
26         }
27 
28         return false;
29     }
30 
31 }

三 实现ImportSelector

1 public class MyImportSelector implements ImportSelector {
 2 
 3     //返回值,就是到导入到容器中的组件全类名
 4     //AnnotationMetadata:当前标注@Import注解的类的所有注解信息
 5     public String[] selectImports(AnnotationMetadata importingClassMetadata) {
 6         // TODO Auto-generated method stub
 7         //importingClassMetadata
 8         //方法不要返回null值
 9         return new String[]{"com.atguigu.bean.Blue","com.atguigu.bean.Yellow"};
10     }
11 
12 }

四 实现ImportBeanDefinitionRegistrar

1 public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
 2 
 3     /**
 4      * AnnotationMetadata:当前类的注解信息
 5      * BeanDefinitionRegistry:BeanDefinition注册类;
 6      *      把所有需要添加到容器中的bean;调用
 7      *      BeanDefinitionRegistry.registerBeanDefinition手工注册进来
 8      */
 9     @Override
10     public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
11         
12         boolean definition = registry.containsBeanDefinition("com.atguigu.bean.Red");
13         boolean definition2 = registry.containsBeanDefinition("com.atguigu.bean.Blue");
14         if(definition && definition2){
15             //指定Bean定义信息;(Bean的类型,Bean。。。)
16             RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
17             //注册一个Bean,指定bean名
18             registry.registerBeanDefinition("rainBow", beanDefinition);
19         }
20     }
21 
22 }

五 实现 FactoryBean

1 / /创建一个Spring定义的FactoryBean
 2 public class ColorFactoryBean implements FactoryBean<Color> {
 3 
 4     //返回一个Color对象,这个对象会添加到容器中
 5     @Override
 6     public Color getObject() throws Exception {
 7         // TODO Auto-generated method stub
 8         System.out.println("ColorFactoryBean...getObject...");
 9         return new Color();
10     }
11 
12     @Override
13     public Class<?> getObjectType() {
14         // TODO Auto-generated method stub
15         return Color.class;
16     }
17 
18     //是单例?
19     //true:这个bean是单实例,在容器中保存一份
20     //false:多实例,每次获取都会创建一个新的bean;
21     @Override
22     public boolean isSingleton() {
23         // TODO Auto-generated method stub
24         return false;
25     }
26 
27 }
28