BeanFactory和FactoryBean的区别

BeanFactory:是用来给具体的IOC容器的实现提供了规范,实现了BeanFactory的接口类表明此类是一个工厂,主要负责初始化各种Bean,并调用他们的生命周期方法。该接口也是IOC容器的顶级接口。

FactoryBean:是一种工厂bean,可以返回bean的实例,可以通过实现该接口对bean进行额外的操作,例如简化配置等。其实在spring中有两种bean,一种是普通的bean,一种是工厂bean即是FactoryBean。

FactoryBean和Bean不同,其返回的对象不是指定类的一个实例,而是该FactrorBean的getObject方法所返回的对象。

在一般情况下,spring通过反射机制利用class属性,指定实现类实例化Bean,在某些情况下,实例化Bean的过程比较复杂,如果按照传统的方式,则需要在中配置大量的配置信息。

1:简化XML配置,隐藏细节:假设一个类有非常多的属性,我们想通过spring对类中的属性进行值的注入,势必会在配置文件中书写大量的属性配置,造成配置文件臃肿,那么此时可以考虑使用FactoryBean来简化配置

新建一个bean

/**
*
* @author Hxd
* @createTime 2020-03-26 20:55:58
**/
public class User {
/** 姓名 */
private String name;
/** 年龄 */
private int age;
/** 班级名称 */
private String className;

public User() {
}

public User(String name, int age, String className) {
this.name = name;
this.age = age;
this.className = className;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getClassName() {
return className;
}

public void setClassName(String className) {
this.className = className;
}

@Override
public String toString() {
return "user{" + "name='" + name + '\'' + ", age=" + age + ", className='" + className + '\'' + '}';
}
}

新建一个FactoryBean
package com.clover.springbootswagger.controller;

import org.springframework.beans.factory.FactoryBean;

/**
*
* @author Huxudong
* @createTime 2020-03-26 21:06:13
**/
public class StudentFactoryBean implements FactoryBean<User> {
private String userInfo;

@Override
public User getObject() throws Exception {
if(userInfo == null) {
throw new IllegalArgumentException("userInfo is required");
}
String[] splitUserInfo = userInfo.split(",");
if(null == splitUserInfo || splitUserInfo.length != 3) {
throw new IllegalArgumentException("userInfo config error");
}

User user = new User();
user.setName(splitUserInfo[0]);
user.setAge(Integer.valueOf(splitUserInfo[1]));
user.setClassName(splitUserInfo[2]);
return user;
}

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

public String getUserInfo() {
return userInfo;
}

public void setUserInfo(String userInfo) {
this.userInfo = userInfo;
}
}

对应的xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

<!--注意:class是StudentFactoryBean而不是Student-->
<bean id="student" class="com.clover.springbootswagger.controller.StudentFactoryBean" p:userInfo="张三,25,三年二班"/>

</beans>

测试类:
import org.mapstruct.AfterMapping;
import org.mapstruct.BeforeMapping;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test1 {
@BeforeMapping
public void before() {
System.out.println("测试开始....");
}

@AfterMapping
public void after() {
System.out.println("测试技术");
}

@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("user.xml");
System.out.println(applicationContext.getBean("user"));
System.out.println(applicationContext.getBean("&user"));
}
}
结果:
---测试开始---

Student{name='张三', age=25, className='二班'}
org.springframework.beans.factory_bean.UserFactoryBean@25hu568

---测试结束---

 

 这样我们就实现了通过BeanFactory接口达到了简化配置文件的作用。另外大家也可以发现getBean(“student”)返回的Student类的实例;而getBean("&student")返回的是StudentFactoryBean实例,即工厂bean其本身。



参考:https://blog.csdn.net/lyc_liyanchao/article/details/82424122
posted @ 2020-03-26 21:23  Cloverlove  阅读(803)  评论(0编辑  收藏  举报