Spring注解驱动开发——Bean的组件注册

组件注册

  • 一. 组件注册-XML文件配置的方式注册组件
    • ①. pom.xml依赖
    • ②. 实体类Person
    • ③. xml配置文件注册Bean
    • ④. IOC容器测试
    • ⑤. 输出结果为
  • 二. 组件注册-@Configuration&@Bean给容器中注册组
    • ①. @Configuration配置类
    • ②. IOC容器测试
  • 三. 组件注册-@ComponentScan-自动扫描组件&指定扫描规则
    • ①. BookController、BookService、BookDao类,分别添加@Controller、@Service、@Repository注解
    • ②. @ComponentScan(value = "com.xizi")注解扫描
    • ③. IOC容器测试
  • 四. 组件注册-自定义TypeFilter指定过滤规则
    • ①. excludeFilters 排除属性
    • ②. includeFilters 包含属性
    • ③. FilterType.ANNOTATION注解匹配,FilterType.ASSIGNABLE_TYPE类型匹配
    • ④. 自定义匹配的规则FilterType.CUSTOM
    • ⑤. MyTypeFilter 实现TypeFilter接口
    • ⑥. IOC容器测试
  • 五. 组件注册-@Scope-设置组件作用域
    • ①. singleton单实例
    • ②. prototype多实例
    • ③. bean的作用域为单例的时候,它在IOC容器中是何时创建
    • ④. bean的作用域为多实例的时候,它在IOC容器中是何时创建
    • ⑤. bean的作用域为多实例的时候,getBean方法获取几次,就创建几次bean的实例
  • 六. 组件注册-@Lazy-bean懒加载
    • ①. 作用域为单例的bean,默认是在容器启动的时候创建实例对象
    • ②. 懒加载的注解:@Lazy+作用域为单例的bean
    • ③. getBean()方法获取的时候,bean的实例对象才会被创建
  • 七. 组件注册-@Conditional-按照条件注册bean
    • ①. LinuxCondition 和WindowsCondition 实现Condition接口
    • ②. 注解配置类MainConfig2
    • ③. 测试IOC容器
    • ④. 修改vm运行环境参数参数
    • ⑤. @Conditional 的这个注解还可以标注在类上,对容器中的组件进行统一设置
  • 八. 组件注册-@Import-给容器中快速导入一个组件
    • ①. Color实体类
    • ②. @Import(Color.class)注解
    • ③. 测试IOC容器
    • ④. Red实体类
    • ⑤. @Import({Color.class,Red.class})注解导入多个组件
  • 九. 组件注册-@Import-使用ImportSelector
    • ①. 自定义逻辑返回需要导入的组件
    • ②. 配置类MainConfig2
    • ③. 源码debug
    • ④. 创建两个实体类Blue和Yellow
    • ⑤. 修改自定义逻辑返回需要导入的组件
    • ⑥. 测试IOC容器
  • 十. 组件注册-@Import-使用ImportBeanDefinitionRegistrar
    • ①. 创建RainBow实体类
    • ②. 自定义一个MyImportBeanDefinitionRegistrar类
    • ③. 配置类MainConfig2
    • ④. 测试IOC容器
  • 十一. 组件注册-使用FactoryBean注册组件
    • ①. 创建一个类,并且实现 FactoryBean 接口
    • ②. 配置类里面进行配置
    • ③. 测试IOC容器

一. 组件注册-XML文件配置的方式注册组件

①. pom.xml依赖

        <dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-starter-webartifactId>dependency>

②. 实体类Person

package com.xizi.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {private String name;private Integer age;}

③. xml配置文件注册Bean


<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="person" class="com.xizi.pojo.Person"><property name="age" value="18">property><property name="name" value="张三">property>bean>
beans>

④. IOC容器测试

public class MainTest {public static void main(String[]args){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");Person person = (Person) applicationContext.getBean("person");System.out.println(person);}
}

⑤. 输出结果为

Person{name=‘张三’, age=18}

二. 组件注册-@Configuration&@Bean给容器中注册组

①. @Configuration配置类

  • Spring注解的方式默认是以配置的方法名来作为这个bean的默认id,如果我们不想要方法名来作为bean的id,我们可以在@Bean这个注解的value属性来进行指定:
@Configuration
public class MainConfig {// 给容器注册一个Bean,类型为返回值的类型,id默认是方法名(可以直接指定value方法值)@Bean(value = "person01")public Person person01() {return new Person("刘备", 19);}
}

②. IOC容器测试

    @Testvoid test1() {// new一个AnnotationConfigApplicationContext,传入配置文件,得到IOC容器ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);// 根据类型获取值Person bean = applicationContext.getBean(Person.class);System.out.println("根据类型获取" + bean);// 根据Id获取,默认Id就是方法名String[] namesForType = applicationContext.getBeanNamesForType(Person.class);for (String name : namesForType) {System.out.println("获取该组件的id是" + name);}}

在这里插入图片描述

三. 组件注册-@ComponentScan-自动扫描组件&指定扫描规则

①. BookController、BookService、BookDao类,分别添加@Controller、@Service、@Repository注解

@Controller
public class BookController {
}
@Service
public class BookService {
}
@Repository
public class BookDao {
}

②. @ComponentScan(value = “com.xizi”)注解扫描

/*** 配置类就等同以前的配置文件*/
@Configuration //告诉Spring这是一个配置类
@ComponentScan(value = "com.xizi")//相当于是xml配置文件里面的
public class MainConfig {//相当于xml配置文件中的标签,告诉容器注册一个bean//之前xml文件中标签有bean的class类型,那么现在注解方式的类型当然也就是返回值的类型//之前xml文件中标签有bean的id,现在注解的方式默认用的是方法名来作为bean的id@Bean(value = "person")//通过这个value属性可以指定bean在IOC容器的idpublic Person person01() {return new Person("lisi",20);}
}

③. IOC容器测试

    @Testpublic void test01() {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);String[] definitionNames = applicationContext.getBeanDefinitionNames();for (String name : definitionNames) {System.out.println(name);}}

在这里插入图片描述

  • 主配置类 MainConfig 也是IOC容器里面的组件,也被纳入了IOC容器的管理
  • @Configuration 这个注解点进去就可以发现这个注解上也标注了 @Component 的这个注解,也纳入到IOC容器中作为一个组件
    在这里插入图片描述

四. 组件注册-自定义TypeFilter指定过滤规则

在这里插入图片描述

  • 过滤规则
    在这里插入图片描述

①. excludeFilters 排除属性

// 配置类==配置文件
@Configuration
@ComponentScan(value = "com.xizi",excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})},useDefaultFilters = true)public class MainConfig {// 给容器注册一个Bean,类型为返回值的类型,id默认是方法名(可以直接指定value方法值)@Bean(value = "person01")public Person person01() {return new Person("刘备", 19);}}

在这里插入图片描述

②. includeFilters 包含属性

// 配置类==配置文件
@Configuration
@ComponentScans(value = {@ComponentScan(value = "com.xizi", includeFilters = {//自定义匹配的规则@Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})}, useDefaultFilters = false)
})
public class MainConfig {// 给容器注册一个Bean,类型为返回值的类型,id默认是方法名(可以直接指定value方法值)@Bean(value = "person01")public Person person01() {return new Person("刘备", 19);}}

在这里插入图片描述

③. FilterType.ANNOTATION注解匹配,FilterType.ASSIGNABLE_TYPE类型匹配

  • FilterType.ANNOTATION 按照注解来进行匹配
  • FilterType.ASSIGNABLE_TYPE 按照给定的类型来进行匹配
// 配置类==配置文件
@Configuration
@ComponentScans(value = {@ComponentScan(value = "com.xizi",includeFilters = {// FilterType.ANNOTATION 按照注解来进行匹配// FilterType.ASSIGNABLE_TYPE 按照给定的类型来进行匹配@Filter(type = FilterType.ANNOTATION, classes = {Controller.class}),//按照给定的类型来进行匹配@Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {BookService.class})},useDefaultFilters = false)
})
public class MainConfig {// 给容器注册一个Bean,类型为返回值的类型,id默认是方法名(可以直接指定value方法值)@Bean(value = "person01")public Person person01() {return new Person("刘备", 19);}}

在这里插入图片描述

④. 自定义匹配的规则FilterType.CUSTOM

  • 使用FilterType.CUSTOM
@Configuration
@ComponentScans(value = {@ComponentScan(value = "com.xizi", includeFilters = {//自定义匹配的规则@Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})}, useDefaultFilters = false)
})
public class MainConfig {// 给容器注册一个Bean,类型为返回值的类型,id默认是方法名(可以直接指定value方法值)@Bean(value = "person01")public Person person01() {return new Person("刘备", 19);}}

⑤. MyTypeFilter 实现TypeFilter接口

package com.xizi.config;import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
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 {@Overridepublic boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {//获取到当前类注解的信息AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();//获取当前类的资源的信息(比如类的路径)Resource resource = metadataReader.getResource();//获取到当前正在扫描的类的信息ClassMetadata classMetadata = metadataReader.getClassMetadata();//类名String className = classMetadata.getClassName();System.out.println("通过自定义的匹配规则--->" + className);if (className.contains("er")) {return true;}return false;}
}

⑥. IOC容器测试

    @Testvoid test2() {// 获取容器中所有组件的名字ApplicationContext ioc = new AnnotationConfigApplicationContext(MainConfig.class);
//        System.out.println(ioc.getBean("bookService")+"--------------");String[] names = ioc.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}}

在这里插入图片描述

五. 组件注册-@Scope-设置组件作用域

①. singleton单实例

@Configuration
public class MainConfig2 {//默认是单实例的@Bean("person")public Person person() {return new Person();}
}
    @Testvoid test3() {// 获取容器中所有组件的名字ApplicationContext ioc = new AnnotationConfigApplicationContext(MainConfig2.class);String[] names = ioc.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}Person bean = ioc.getBean(Person.class);Person bean1 = ioc.getBean(Person.class);System.out.println(bean==bean1);}

在这里插入图片描述

②. prototype多实例

在这里插入图片描述在这里插入图片描述

@Configuration
public class MainConfig2 {//singleton:单实例的//prototype:多实例的//request:同一次请求创建一个实例//session:同一个session创建的一个实例@Scope("prototype")//默认是单实例的@Bean("person")public Person person() {return new Person();}}

在这里插入图片描述

③. bean的作用域为单例的时候,它在IOC容器中是何时创建

在这里插入图片描述

④. bean的作用域为多实例的时候,它在IOC容器中是何时创建

在这里插入图片描述

⑤. bean的作用域为多实例的时候,getBean方法获取几次,就创建几次bean的实例

在这里插入图片描述

六. 组件注册-@Lazy-bean懒加载

  • 懒加载:是专门针对于单实例的bean的

  • 单实例的bean:默认是在容器启动的时候创建对象;

  • 懒加载:容器启动的时候,不创建对象,而是在第一次使用(获取)Bean的时候来创建对象,并进行初始化

①. 作用域为单例的bean,默认是在容器启动的时候创建实例对象

在这里插入图片描述

②. 懒加载的注解:@Lazy+作用域为单例的bean

在这里插入图片描述

  • 这个时候,只有IOC容器启动了,而作用域为单例的bean并没有被创建

③. getBean()方法获取的时候,bean的实例对象才会被创建

在这里插入图片描述

七. 组件注册-@Conditional-按照条件注册bean

  • 现在有两个bean: bill 和 linus ,现在我们想按照操作系统的不同来选择是否在IOC容器里面注册bean:

  • 现在下面的两个bean注册到IOC容器是要条件的:

    1. 如果系统是windows,给容器注册(“bill”)
    2. 如果系统是linux,给容器注册(“linus”)

①. LinuxCondition 和WindowsCondition 实现Condition接口

/*** 判断操作系统是否为Linux系统*/
public class LinuxCondition implements Condition {/***  ConditionContext : 判断条件能使用的上下文(环境)*  AnnotatedTypeMetadata : 注释信息* @return*/@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {//判断是否为Linux系统//1.能获取到IOC容器里面的BeanFactoryConfigurableListableBeanFactory beanFactory = context.getBeanFactory();//2.获取类加载器ClassLoader classLoader = context.getClassLoader();//3.能获取当前环境的信息Environment environment = context.getEnvironment();//4.获取到bean定义的注册类BeanDefinitionRegistry registry = context.getRegistry();//获取操作系统String property = environment.getProperty("os.name");if (property.contains("linux")) {return true;}return false;}
}
/*** 判断操作系统是否为Windows系统*/
public class WindowsCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {//3.能获取当前环境的信息Environment environment = context.getEnvironment();//获取操作系统String property = environment.getProperty("os.name");if (property.contains("Windows")) {return true;}return false;}
}

②. 注解配置类MainConfig2

//类中组件统一设置。满足当前条件,这个类中配置的所有bean注册才能生效;
@Conditional({WindowsCondition.class})
@Configuration
public class MainConfig2 {/***  现在下面的两个bean注册到IOC容器是要条件的:*  1.如果系统是windows,给容器注册("bill")*  1.如果系统是linux,给容器注册("linus")* @return*/
//    @Conditional({WindowsCondition.class})@Bean("bill")public Person person01() {return new Person("Bill Gates",62);}@Conditional({LinuxCondition.class})@Bean("linus")public Person person02() {return new Person("linus",48);}

③. 测试IOC容器

    @Testpublic void test5() {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);//我们可以获取当前的操作系统是什么:Environment environment = applicationContext.getEnvironment();//动态的获取环境变量的值:Windows 10String property = environment.getProperty("os.name");System.out.println(property);//获取IOC容器类型为Person类型的bean的名字一共有哪些String[] definitionNames = applicationContext.getBeanNamesForType(Person.class);for (String name : definitionNames) {System.out.println(name);}//我们也可以来获取类型为Person类型的对象Map<String, Person> persons = applicationContext.getBeansOfType(Person.class);persons.values().forEach(System.out::println);}

在这里插入图片描述

④. 修改vm运行环境参数参数

在这里插入图片描述在这里插入图片描述

⑤. @Conditional 的这个注解还可以标注在类上,对容器中的组件进行统一设置

在这里插入图片描述

八. 组件注册-@Import-给容器中快速导入一个组件

  • @Import[快速的给容器中导入一个组件]
    (1)、 @Import(要导入容器中的组件);容器中就会自动的注册这个组件,id默认是全类名
    (2)、 ImportSelector :返回需要的组件的全类名的数组;
    (3)、 ImportBeanDefinitionRegistrar : 手动注册bean到容器中

  • ImportSelector 这种用法在SpringBoot里面用的非常的多;

①. Color实体类

public class Color {
}

②. @Import(Color.class)注解

  • 使用了 @Import(Color.class)注解之后,我们可以看到IOC容器里面就有这个组件了,id默认就是这个组件的全类名
@Configuration
//满足当前条件,这个类中配置的所有bean注册才能生效
@Conditional({WindowsCondition.class})
//快速导入组件,id默认是组件的全类名
@Import(Color.class)
public class MainConfig2 {/*** @Conditional:是SpringBoot底层大量使用的注解,按照一定的条件来进行判断,满足条件 给容器注册bean*//***  现在下面的两个bean注册到IOC容器是要条件的:*  1.如果系统是windows,给容器注册("bill")*  1.如果系统是linux,给容器注册("linus")* @return*/@Bean("bill")public Person person01() {return new Person("Bill Gates",62);}@Conditional({LinuxCondition.class})@Bean("linus")public Person person02() {return new Person("linus",48);}/*** 给容器中注册组件:* 1)、扫描+组件标注注解(@Controller/@Service/@Repository/@Component)* 【局限于要求是自己写的类,如果导入的第三方没有添加这些注解,那么就注册不上了】** 2)、@Bean[导入的第三方包里面的组件]* 3)、@Import[快速的给容器中导入一个组件]*/
}

③. 测试IOC容器

    @Testpublic void test4() {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);printBeans(applicationContext);}private void printBeans(ApplicationContext applicationContext) {String[] definitionNames = applicationContext.getBeanDefinitionNames();for (String name : definitionNames) {System.out.println(name);}}

在这里插入图片描述

④. Red实体类

public class Red {
}

⑤. @Import({Color.class,Red.class})注解导入多个组件

在这里插入图片描述

@Configuration
//满足当前条件,这个类中配置的所有bean注册才能生效
@Conditional({WindowsCondition.class})
//快速导入组件,id默认是组件的全类名
@Import({Color.class,Red.class})
public class MainConfig2 {/*** @Conditional:是SpringBoot底层大量使用的注解,按照一定的条件来进行判断,满足条件 给容器注册bean*//***  现在下面的两个bean注册到IOC容器是要条件的:*  1.如果系统是windows,给容器注册("bill")*  1.如果系统是linux,给容器注册("linus")* @return*/@Bean("bill")public Person person01() {return new Person("Bill Gates",62);}@Conditional({LinuxCondition.class})@Bean("linus")public Person person02() {return new Person("linus",48);}/*** 给容器中注册组件:* 1)、扫描+组件标注注解(@Controller/@Service/@Repository/@Component)* 【局限于要求是自己写的类,如果导入的第三方没有添加这些注解,那么就注册不上了】** 2)、@Bean[导入的第三方包里面的组件]* 3)、@Import[快速的给容器中导入一个组件]*/
}

在这里插入图片描述

九. 组件注册-@Import-使用ImportSelector

①. 自定义逻辑返回需要导入的组件

//自定义逻辑返回需要导入的组件
public class MyImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[0];}
}

②. 配置类MainConfig2

@Configuration
//满足当前条件,这个类中配置的所有bean注册才能生效
@Conditional({WindowsCondition.class})
//快速导入组件,id默认是组件的全类名
@Import({Color.class,Red.class,MyImportSelector.class})
public class MainConfig2 {/*** @Conditional:是SpringBoot底层大量使用的注解,按照一定的条件来进行判断,满足条件 给容器注册bean*//***  现在下面的两个bean注册到IOC容器是要条件的:*  1.如果系统是windows,给容器注册("bill")*  1.如果系统是linux,给容器注册("linus")* @return*/@Bean("bill")public Person person01() {return new Person("Bill Gates",62);}@Conditional({LinuxCondition.class})@Bean("linus")public Person person02() {return new Person("linus",48);}/*** 给容器中注册组件:* 1)、扫描+组件标注注解(@Controller/@Service/@Repository/@Component)* 【局限于要求是自己写的类,如果导入的第三方没有添加这些注解,那么就注册不上了】** 2)、@Bean[导入的第三方包里面的组件]* 3)、@Import[快速的给容器中导入一个组件]*      (1)、 @Import(要导入容器中的组件);容器中就会自动的注册这个组件,id默认是全类名*      (2)、 ImportSelector :返回需要的组件的全类名的数组;*/
}

③. 源码debug

在这里插入图片描述在这里插入图片描述在这里插入图片描述

④. 创建两个实体类Blue和Yellow

public class Blue {
}
public class Yellow {
}

⑤. 修改自定义逻辑返回需要导入的组件

//自定义逻辑返回需要导入的组件
public class MyImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{"com.xizi.pojo.Blue","com.xizi.pojo.Yellow"};}
}

在这里插入图片描述

⑥. 测试IOC容器

    @Testpublic void test4() {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);printBeans(applicationContext);}private void printBeans(ApplicationContext applicationContext) {String[] definitionNames = applicationContext.getBeanDefinitionNames();for (String name : definitionNames) {System.out.println(name);}}

在这里插入图片描述

十. 组件注册-@Import-使用ImportBeanDefinitionRegistrar

①. 创建RainBow实体类

public class RainBow {
}

②. 自定义一个MyImportBeanDefinitionRegistrar类

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {/**** AnnotationMetadata 当前类的注解信息* BeanDefinitionRegistry BeanDefinition注册类** 我们把所有需要添加到容器中的bean通过BeanDefinitionRegistry里面的registerBeanDefinition方法来手动的进行注册*/@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {//判断IOC容器里面是否含有这两个组件boolean definition = registry.containsBeanDefinition("com.ldc.bean.Red");boolean definition2 = registry.containsBeanDefinition("com.ldc.bean.Blue");//如果有的话,我就把RainBow的bean的实例给注册到IOC容器中if (definition && definition2) {//指定bean的定义信息,参数里面指定要注册的bean的类型:RainBow.classRootBeanDefinition rootBeanDefinition = new RootBeanDefinition(RainBow.class);//注册一个bean,并且指定bean名registry.registerBeanDefinition("rainBow", rootBeanDefinition );}}
}

在这里插入图片描述
在这里插入图片描述

③. 配置类MainConfig2

@Configuration
//满足当前条件,这个类中配置的所有bean注册才能生效
@Conditional({WindowsCondition.class})
//快速导入组件,id默认是组件的全类名
@Import({Color.class,Red.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
public class MainConfig2 {/*** @Conditional:是SpringBoot底层大量使用的注解,按照一定的条件来进行判断,满足条件 给容器注册bean*//***  现在下面的两个bean注册到IOC容器是要条件的:*  1.如果系统是windows,给容器注册("bill")*  1.如果系统是linux,给容器注册("linus")* @return*/@Bean("bill")public Person person01() {return new Person("Bill Gates",62);}@Conditional({LinuxCondition.class})@Bean("linus")public Person person02() {return new Person("linus",48);}/*** 给容器中注册组件:* 1)、扫描+组件标注注解(@Controller/@Service/@Repository/@Component)* 【局限于要求是自己写的类,如果导入的第三方没有添加这些注解,那么就注册不上了】** 2)、@Bean[导入的第三方包里面的组件]* 3)、@Import[快速的给容器中导入一个组件]*      (1)、 @Import(要导入容器中的组件);容器中就会自动的注册这个组件,id默认是全类名*      (2)、 ImportSelector :返回需要的组件的全类名的数组;*      (3)、 ImportBeanDefinitionRegistrar : 手动注册bean到容器中*/
}

④. 测试IOC容器

    @Testpublic void test4() {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);printBeans(applicationContext);}private void printBeans(ApplicationContext applicationContext) {String[] definitionNames = applicationContext.getBeanDefinitionNames();for (String name : definitionNames) {System.out.println(name);}}

在这里插入图片描述

十一. 组件注册-使用FactoryBean注册组件

  • 使用Spring提供的FactoryBean(工厂bean)
    (1)、默认获取到的是工厂bean调用getObject创建的对象
    (2)、要获取工厂bean本身,我们需要给id前面加上一个“&”符号:&colorFactoryBean

①. 创建一个类,并且实现 FactoryBean 接口

package com.xizi.pojo;import org.springframework.beans.factory.FactoryBean;//创建一个Spring定义的FactoryBean
public class ColorFactoryBean implements FactoryBean<Color> {//返回一个Color对象,这个对象会添加到容器中@Overridepublic Color getObject() throws Exception {System.out.println("ColorFactoryBean...getBean...");return new Color();}//返回的类型@Overridepublic Class<?> getObjectType() {return Color.class;}//控制是否为单例// true:表示的就是一个单实例,在容器中保存一份// false:多实例,每次获取都会创建一个新的bean@Overridepublic boolean isSingleton() {return true;}
}

②. 配置类里面进行配置

@Configuration
//满足当前条件,这个类中配置的所有bean注册才能生效
@Conditional({WindowsCondition.class})
//快速导入组件,id默认是组件的全类名
@Import({Color.class,Red.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
public class MainConfig2 {/*** @Conditional:是SpringBoot底层大量使用的注解,按照一定的条件来进行判断,满足条件 给容器注册bean*//***  现在下面的两个bean注册到IOC容器是要条件的:*  1.如果系统是windows,给容器注册("bill")*  1.如果系统是linux,给容器注册("linus")* @return*/@Bean("bill")public Person person01() {return new Person("Bill Gates",62);}@Conditional({LinuxCondition.class})@Bean("linus")public Person person02() {return new Person("linus",48);}/*** 给容器中注册组件:* 1)、扫描+组件标注注解(@Controller/@Service/@Repository/@Component)* 【局限于要求是自己写的类,如果导入的第三方没有添加这些注解,那么就注册不上了】** 2)、@Bean[导入的第三方包里面的组件]* 3)、@Import[快速的给容器中导入一个组件]*      (1)、 @Import(要导入容器中的组件);容器中就会自动的注册这个组件,id默认是全类名*      (2)、 ImportSelector :返回需要的组件的全类名的数组;*      (3)、 ImportBeanDefinitionRegistrar : 手动注册bean到容器中** 4)、使用Spring提供的FactoryBean(工厂bean)*      (1)、默认获取到的是工厂bean调用getObject创建的对象*      (2)、要获取工厂bean本身,我们需要给id前面加上一个“&”符号:&colorFactoryBean*/@Beanpublic ColorFactoryBean colorFactoryBean() {return new ColorFactoryBean();}
}

在这里插入图片描述

③. 测试IOC容器

    @Testpublic void test6() {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);printBeans(applicationContext);//工厂bean获取的是调用getObject方法创建的对象Object colorFactoryBean = applicationContext.getBean("colorFactoryBean");System.out.println("bean的类型:"+colorFactoryBean.getClass());//如果我们就想要获取这个工厂bean,我们就可以在id的前面加上一个"&"符号Object colorFactoryBean2 = applicationContext.getBean("&colorFactoryBean");System.out.println("bean的类型:"+colorFactoryBean2.getClass());}

在这里插入图片描述


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部