文章目录
- FactoryBean 和 BeanFactory
- 后置处理器BeanPostProcessor 和 BeanFactoryPostProcessor
- BeanPostProcessor
- BeanFactoryPostProcessor
FactoryBean 和 BeanFactory
BeanFactory
接⼝是容器的顶级接⼝,定义了容器的⼀些基础⾏为,负责⽣产和管理Bean的⼀个⼯⼚,具体使⽤它下⾯的⼦接⼝类型,⽐如ApplicationContext;此处我们重点分析FactoryBean。
Spring中Bean有两种,⼀种是普通Bean,⼀种是⼯⼚Bean(FactoryBean),FactoryBean
可以⽣成某⼀个类型的Bean实例(返回给我们),也就是说我们可以借助于它⾃定义Bean的创建过程。
Bean创建的三种⽅式中的静态⽅法和实例化⽅法和FactoryBean作⽤类似,FactoryBean使⽤较多,尤其在Spring框架⼀些组件中会使⽤,还有其他框架和Spring框架整合时使⽤。
// 可以让我们⾃定义Bean的创建过程(完成复杂Bean的定义)public interface FactoryBean<T> { @Nullable // 返回FactoryBean创建的Bean实例,如果isSingleton返回true,则该实例会放到Spring容器的单例对象缓存池中Map T getObject() throws Exception; @Nullable // 返回FactoryBean创建的Bean类型 Class<?> getObjectType(); // 返回作⽤域是否单例 default boolean isSingleton() { return true; }}
User类
public class User { private String name; private String addr; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddr() { return addr; } public void setAddr(String addr) { this.addr = addr; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", addr='" + addr + '\'' + '}'; }}
UserFactoryBean类
public class UserFactoryBean implements FactoryBean<Company> { private String userInfo; // 用户姓名,地址 public void setUserInfo(String userInfo) { this.userInfo = userInfo; } @Override public User getObject() throws Exception { // 模拟创建复杂对象User User user = new User(); String[] strings = userInfo.split(","); user.setName(strings[0]); user.setAddr(strings[1]); return user; } @Override public Class<?> getObjectType() { return User.class; } @Override public boolean isSingleton() { return true; }}
xml配置
<bean id="userBean" class="com.zjq.factory.UserFactoryBean"> <property name="userInfo" value="詹先生,hangzhou"/></bean>
测试,获取FactoryBean产⽣的对象
Object userBean = applicationContext.getBean("userBean");System.out.println("bean:" + userBean);
结果如下:
bean:User{name=‘詹先生’, addr=‘hangzhou’}
测试,获取FactoryBean,需要在id之前添加“&”
Object userBean = applicationContext.getBean("&userBean");System.out.println("bean:" + userBean);
结果如下:
bean:com.zjq.factory.UserFactoryBean@65f6cd78
后置处理器BeanPostProcessor 和 BeanFactoryPostProcessor
Spring提供了两种后处理bean的扩展接⼝,分别为 BeanPostProcessor
和 BeanFactoryPostProcessor
,两者在使⽤上是有所区别的。
⼯⼚初始化(BeanFactory)—> Bean对象
在BeanFactory初始化之后
可以使⽤BeanFactoryPostProcessor进⾏后置处理做⼀些事情
在Bean对象实例化(并不是Bean的整个⽣命周期完成)之后
可以使⽤BeanPostProcessor进⾏后置处
理做⼀些事情
注意:对象不⼀定是springbean,⽽springbean⼀定是个对象
BeanPostProcessor
BeanPostProcessor是针对Bean级别
的处理,可以针对某个具体的Bean。
public interface BeanPostProcessor { @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; }}
该接⼝提供了两个⽅法,分别在Bean的初始化⽅法前和初始化⽅法后执⾏,具体这个初始化⽅法指的是什么⽅法,类似我们在定义bean时,定义了init-method
所指定的⽅法。
定义⼀个类实现了BeanPostProcessor,默认是会对整个Spring容器中所有的bean进⾏处理。如果要对具体的某个bean处理,可以通过⽅法参数判断,两个类型参数分别为Object和String,第⼀个参数是每个bean的实例,第⼆个参数是每个bean的name或者id属性的值。所以我们可以通过第⼆个参数,来判断我们将要处理的具体的bean。
注意:处理是发⽣在Spring容器的实例化和依赖注⼊之后。
BeanFactoryPostProcessor
BeanFactory级别的处理,是针对整个Bean的⼯⼚进⾏处理,典型应⽤:PropertyPlaceholderConfifigurer
此接⼝只提供了⼀个⽅法,⽅法参数为ConfifigurableListableBeanFactory,该参数类型定义了⼀些⽅法:
其中有个⽅法名为getBeanDefifinition的⽅法,我们可以根据此⽅法,找到我们定义bean的BeanDefifinition
对象。然后我们可以对定义的属性进⾏修改,以下是BeanDefifinition中的⽅法:
⽅法名字类似我们bean标签的属性
,setBeanClassName对应bean标签中的class属性,所以当我们拿到BeanDefifinition对象时,我们可以⼿动修改bean标签中所定义的属性值。
**BeanDefifinition对象:**我们在 XML 中定义的 bean标签,Spring 解析 bean 标签成为⼀个 JavaBean,这个JavaBean 就是 BeanDefifinition 。
注意:调⽤ BeanFactoryPostProcessor ⽅法时,这时候bean还没有实例化,此时 bean 刚被解析成BeanDefifinition对象。
本文内容到此结束了,
如有收获欢迎点赞收藏关注✔️,您的鼓励是我最大的动力。
如有错误❌疑问欢迎各位指出。
主页:共饮一杯无的博客汇总保持热爱,奔赴下一场山海。