[springboot注解 容器篇] FactoryBean

FactoryBean不是注解,但是使用它可以直接向容器中注册bean,所以这里也介绍一下

这里直接上例子,然后通过例子来讲解其实用。

例子

首先创建FactoryBean的实现类

// 这个类就不单独占用地方了,就写在这里了
public class Animal {
}

public class AnimalFactoryBean implements FactoryBean<Animal> {
    // 当调用getBean这样的方法从容器中后去bean时,就会调用这个方法
    // 非单例模式下调用getBean时,就会执行这个方法来创建bean
    // 单例模式下,会先先调用这个方法生成bean,然后放到容器中,在调用getBean时直接从容器中拿,因为不会在调用这个方法,多以就是单例了
    @Override
    public Animal getObject() throws Exception {
        System.out.println("获取bean....");
        return new Animal();
    }

    @Override
    public Class<?> getObjectType() {
        return Animal.class;
    }

    // 设置是否为单例,true:单例,容器中是保存一份;false:非单例,每次获取时都创建一个新的实例
    @Override
    public boolean isSingleton() {
        return true;
    }
}

然后,在配置类中将FactoryBean的实现类生成的bean放到容器中 

@Configuration // 相当于写了一个spring的xml配置文件
public class MyConfig {
    // 创建一个FactoryBean,虽然是将AnimalFactoryBean放到了容器中,但是当调用getBean时,获取的不是AnimalFactoryBean,而是会调用AnimalFactoryBean中的getObject方法生成的bean。具体看main方法给出的注释。    
    @Bean
    public AnimalFactoryBean animalFactoryBean(){
        return new AnimalFactoryBean();
    }
}

最后,从容器中获取bean,这里注意观察截图中【1】【2】标注,下面会有解说 

public class AppliactionRunner {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        String[] names = applicationContext.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name); //【1】打印出容器中所有的bean名字,
        }

        //【2】getBean时会调用容器中animalFactgoryBean的getObjec,然后返回方法中生成的对象
        Object animalFactgoryBean = applicationContext.getBean("animalFactoryBean");
        System.out.println("bean的类型" + animalFactgoryBean.getClass());
    }
}

运行结果:

 上面我们就完成了一个FactoryBean的使用。它的作用就是可以让我们自定义bean的创建过程,如下场景:

//Animal是个接口    
@Override
    public Animal getObject() throws Exception {
        // return的都是Animal的实现类
        if(今天周一){
            return new 小狗(); 
        }
        if(今天周二){
            return new 小猫();
        }
    }

这样我们就可以自定义bean的创建过程,根据条件返回不同的bean,当然必须是返回一个接口的实现类才行。然后当调用getBean的时候,就可以获取到这里根据业务返回的不同的实现类了,然后再用接口接收一下就行了。

另外,大家可能注意到打印结果和main方法中标注了【1】【2】两个地方,这也是使用FactoryBean的要注意的地方。下面我说明一下:
当在配置类通过@Bean向容器放入我们写的FactoryBean的实现类后,这个Bean会被放到容器中,这个通过【1】处的打印可得知。但是,当我们通过getBean获取这个bean时,有意思的事情发生了,注意观察【2】打印的结果,这个我们获取到的bean确实Animal这个类,这就是FactoryBean的特点和作用,虽然放到容器中的时FactoryBean的实现了,但是当getBean获取bean时,会调用这个实现类中的getObject方法,然后把里面return的对象返回。这个一定要记住昂。

那么有人会说,如果我就想用getBean获取FactoryBean的实现类,也就是我们例子中的AnimalFactoryBean的对象怎么办呢,其实很简单,方法如下:

// 将【2】改成这么写就行,加个&就行了
Object animalFactgoryBean = applicationContext.getBean("&animalFactoryBean");

为什么&就会拿到FactoryBean本身的那个实现类的对象呢,这是BeanFactory这个接口的作用,看源码
 

 这里定义了一个&,如果使用一个&前缀,spring容器就会知道要拿FactoryBean(工程bean)的本身。

提示:一定要分清FactoryBean和BeanFactory的区别,别混了

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot,你可以通过实现`FactoryBean`、`ApplicationContextAware`和`InitializingBean`接口来自定义Bean的创建和初始化过程。 首先,让我们看看如何实现`FactoryBean`接口: ```java import org.springframework.beans.factory.FactoryBean; public class MyFactoryBean implements FactoryBean<MyBean> { @Override public MyBean getObject() throws Exception { // 创建并返回自定义的Bean对象 return new MyBean(); } @Override public Class<?> getObjectType() { return MyBean.class; } @Override public boolean isSingleton() { return true; // 返回true表示该Bean是单例的 } } ``` 在上面的示例,`MyFactoryBean`类实现了`FactoryBean`接口,并重写了`getObject()`、`getObjectType()`和`isSingleton()`方法。通过实现这些方法,你可以定义自己的逻辑来创建和配置Bean。 接下来,让我们看看如何实现`ApplicationContextAware`接口: ```java import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContext; public class MyApplicationContextAware implements ApplicationContextAware { private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } // 可以在这里使用applicationContext访问其他Bean或执行其他操作 } ``` 在上面的示例,`MyApplicationContextAware`类实现了`ApplicationContextAware`接口,并重写了`setApplicationContext()`方法。通过重写该方法,你可以在Bean初始化时获得`ApplicationContext`对象,并在需要时使用它。 最后,让我们看看如何实现`InitializingBean`接口: ```java import org.springframework.beans.factory.InitializingBean; public class MyInitializingBean implements InitializingBean { @Override public void afterPropertiesSet() throws Exception { // 在这里执行Bean的初始化逻辑 } } ``` 在上面的示例,`MyInitializingBean`类实现了`InitializingBean`接口,并重写了`afterPropertiesSet()`方法。在该方法,你可以实现自定义的Bean初始化逻辑。 请注意,以上示例的类都是自定义的类,你需要将它们注册为Spring Bean,可以使用`@Component`注解或在配置类进行配置。例如,在配置类添加如下代码: ```java @Configuration public class AppConfig { @Bean public MyFactoryBean myFactoryBean() { return new MyFactoryBean(); } @Bean public MyApplicationContextAware myApplicationContextAware() { return new MyApplicationContextAware(); } @Bean public MyInitializingBean myInitializingBean() { return new MyInitializingBean(); } } ``` 通过以上配置,你可以将自定义的FactoryBean、ApplicationContextAware和InitializingBean注册为Spring Bean,并在应用使用它们。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值