【Spring注解系列06】FactoryBean注入对象用法

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


实例类与配置类

public class Color {
}

//创建一个Spring定义的FactoryBean
public class ColorFactoryBean implements FactoryBean {

    @Nullable
    @Override
    public Color getObject() throws Exception {
        System.out.println("ImportBeanByFactoryBean...............getObject");
        return new Color();
    }

    @Nullable
    @Override
    public Class getObjectType() {
        return Color.class;
    }

    //是否为单例,默认为true,单实例。false表示为多实例
    @Override
    public boolean isSingleton() {
        return true;
    }
}

@Configuration
public class FactoryBeanConfig {

    /**
     * 使用Spring提供的 FactoryBean(工厂Bean);
     * 		1)、默认获取到的是工厂bean调用getObject创建的对象
     * 		2)、要获取工厂Bean本身,我们需要给id前面加一个&
     * 			&colorFactoryBean
     */
    @Bean
    public ColorFactoryBean colorFactoryBean(){
        return new ColorFactoryBean();
    }
}

测试

public class FactoryBeanTest {

    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(FactoryBeanConfig.class);

        //bean1看到的好像是ColorFactoryBean,实际上是Color的bean
        Object bean1 = applicationContext.getBean("colorFactoryBean");
        Object bean2 = applicationContext.getBean("colorFactoryBean");
        System.out.println(bean1);
        System.out.println(bean1==bean2);//设置为isSingleton返回值为true时,为单例

        //获取ColorFactoryBean本身
        ColorFactoryBean colorFactoryBean = (ColorFactoryBean) applicationContext.getBean("&colorFactoryBean");
        System.out.println(colorFactoryBean);

    }
}


结果:
ImportBeanByFactoryBean...............getObject //调用factoryBean的getObject方法
com.java.model.Color@2df32bf7 //注入对象实际为Color,而不是ColorFactoryBean
true //单例相同
com.java.model.ColorFactoryBean@530612ba //获取本身

个人觉得FactoryBean没什么作用,既然要单独注入Factorybean的实现类,为什么不直接注入要注入的对象呢?

Spring底层好像有大量应用。查看了一下FactoryBean的实现类,这个大部分都是用于代理对象。 用法值得再深入了解一下。

factoryBean接口上的注释:

* 

This interface is heavily used within the framework itself, for example for * the AOP {@link org.springframework.aop.framework.ProxyFactoryBean} or the * {@link org.springframework.jndi.JndiObjectFactoryBean}. It can be used for * custom components as well; however, this is only common for infrastructure code. *意思:该接口主要用于Spring框架内部,比如AOP或者JndiObjectFactoryBean等。它也能用于自定义组件, *但是只适用于有共同基础架构代码的组件。 * *

{@code FactoryBean} is a programmatic contract. Implementations are not * supposed to rely on annotation-driven injection or other reflective facilities. * {@link #getObjectType()} {@link #getObject()} invocations may arrive early in * the bootstrap process, even ahead of any post-processor setup. If you need access * other beans, implement {@link BeanFactoryAware} and obtain them programmatically. *意思:factoryBean是一个工程契约。实现它不应该依赖于注解驱动注入或者其他反射协助。 * getObjectType和getObject方法调用可能在引导程序处理之前,甚至在后置处理器赋值之前。 * 如果操作时需要访问其他bean,则需要实现BeanFactoryAware接口,来获得这些工程对象。 * *

Finally, FactoryBean objects participate in the containing BeanFactory's * synchronization of bean creation. There is usually no need for internal * synchronization other than for purposes of lazy initialization within the * FactoryBean itself (or the like). *意思:最后,FactoryBean对象参与包含BeanFactory的bean创建同步。除了在FactoryBean本身 * (或类似的)中进行延迟初始化之外,通常不需要内部同步。

 

你可能感兴趣的:(Spring,Spring)