1. FactoryBean是什么?
在Spring中有两种类型的bean,一种是普通Bean,一种是工厂Bean,即FactoryBean。字面意思来看FactoryBean的作用就是用来生成Bean的工厂。
FactoryBean其实是一个接口,这个接口里有三个方法,如下:
getObject()方法会返回该FactoryBean"生产"的对象实例,我们需要实现该方法以给出自己的对象实例化逻辑;
getObjectType()方法仅返回getObject()方法所返回的对象的类型,如果预先无法确定,则返回null;
isSingleton()方法返回结果用于表明,工厂方法getObject()所"生产"的对象是否要以singleton形式存在于容器中。如果以singleton形式存在,则返回true,否则返回false;
FactoryBean跟普通bean不同,ta返回的对象不是指定类的一个实例,而是FactoryBean的getObject方法所返回的对象。
理解了FactoryBean是什么之后,我们要继续思考一个问题:Spring明明可以通过反射利用class属性来生成Bean,为什么又引入了FactoryBean呢?
2. 为什么需要FactoryBean?
Spring之所以引入FactoryBean来生成Bean,主要是因为如果Bean的创建过程比较复杂,需要涉及很多业务逻辑处理或者多个参数的初始化等,用xml配置文件的方式实现起来比较麻烦。而利用FactoryBean采取编码的方式来简化这些繁琐配置,使得对上层应用隐藏这些复杂的细节配置,给上层应用带来了便利。
那 一般是用来干什么的?
一般用在框架中,用于创建复杂的 bean 实例,例如 SpringAOP 中的 用于创建 AOP 代理,Dubbo 中的 用于创建远程服务代理。
另外,比如在rpc中消费者需要向调用本地服务一样调用远程服务,此时会将远程服务调用过程封装,使得调用方无感知,再比如在我们希望对自定义的Bean的所有方法做一个拦截,在方法执行前后都输出日志,或者自定义一个Bean,该Bean包含了其他复杂的bean等等。
使用FactoryBean简单demo
将上面的StudentFactoryBean使用注解的方式注册到Spring容器中
运行如下语句
输出
可以看到如果我们通过FactoryBean默认的beanName从Spring容器中获取bean,获取到的并不是FactoryBean本身,而是由它产生的Bean(Student),要想获取FactoryBean本身,需要使用&+beanName
3. 使用场景
3.1 场景一:rpc调用
3.1.1 自定义RpcConsumerProxyFactoryBean
3.1.2 RemoteService接口
3.1.3 Spring上下文配置
3.1.4 测试&运行结果
运行结果:
3.2 场景二:方法拦截
3.2.1 自定义CustomFactoryBean
3.2.2 CustomService接口
3.2.3 CustomService接口实现
3.2.4 Spring上下文配置
3.2.5 测试&运行结果
运行结果:
4. 总结
FactoryBean是一个接口,我更倾向于把他看做是一种设计模式。当我们自定义一个FactoryBean的时候,需要重写FactoryBean接口里的三个方法,我们可以把一些复杂的代码逻辑(比如上述两个示例的动态代理操作)放在getObject中。以便于对上层应用的一个隐藏从而便于上层应用的调用。
的优点是可以自定义构建 bean ,使得创建bean的过程更加灵活。
本身可以理解成是一种策略模式,我们需要生成什么样的 bean,可以通过实现接口来自定义。这就将创建对象的行为独立出来了,符合前闭后开的原则,是一种非侵入的方式,达到了解耦的目的
我们平常的工作一般可能用不到 ,但是了解有这样一种机制对我们也是一种提升。
热爱技术才能学好技术
每天进步一点点
领取专属 10元无门槛券
私享最新 技术干货