beanfactory篇-(四)FactoryBean的基本使用-九零后大叔的技术博客

沙海
沙海
沙海
1017
文章
2
评论
2021年4月24日09:12:02
评论
1 4556字阅读15分11秒
摘要

回顾:通过前面一个章节的了解,我们学会了bean的lookup-method和replace-method这个两个重要属性的用法。那么本章节,我们学习一个工作中使用不太频繁的一个属性,也就是factoryBean属性。

回顾:通过前面一个章节的了解,我们学会了bean的lookup-method和replace-method这个两个重要属性的用法。那么本章节,我们学习一个工作中使用不太频繁的一个属性,也就是factoryBean属性。

1. factoryBean的基本概念介绍

我们观察前面的业务bean对象的创建,直接通过beanFactory或者applicationContext对象的getBean方法就获取到了,不像我们平时使用的new UserServiceImpl()方法,也不像我们平时使用的通过反射的getInstance方法获取到的,整个创建业务对象的过程对于开发者而言就是一个黑盒。本章节我们暂时不考虑业务对象是如何创建的(先提前泄露一下答案:绝大部分都是通过反射创建的,但是spring也留下了允许开发者自己创建bean的口子),那么如果我有一个需求,我想bean的创建由开发者自己掌握(也就是由开发者自己写代码,即new UserServiceImpl()方式去创建一个bean),而不是委托给spring容器去创建,是否可以呢?强大的spring框架是支持这一点的,怎么支持的?就是通过就是FactoryBean扩展机制实现的。

2. factoryBean的基本使用

鉴于spring的几乎所有功能都存在xml配置和注解两种方式来使用,那么本章的内容将两种方式都进行讲解。
[1]基于xml方式,由开发者自己创建bean对象然后委托给spring容器管理

第一步:创建一个User实体类

@Data
@NoArgsConstructor
@ToString
@EqualsAndHashCode
public class User implements Serializable {

    private static final long serialVersionUID = 4800166777883697833L;

    private Long id;
    private String name;
    private String identity;
    private String mobile;
    private String bankcard;
    private Integer age;
    private Integer gender;

}

第二步:我们创建一个接口和接口实现类

public interface UserService {

    User findUserById(Long id);

}

public class UserServiceImpl implements UserService {

    @Override
    public User findUserById(Long id) {

        User user = new User();
        user.setId(id);
        user.setName("张山");
        user.setIdentity("张山");
        user.setBankcard("36457736355363");
        user.setMobile("16752652625");
        user.setGender(2);
        user.setAge(18);

        return user;
    }

}

第三步:然后关键步骤来了,我们创建一个工厂bean用于创建UserServiceImpl实例

public class UserServiceXmlFactoryBean {

    public UserService createUserService() {
        //开发者自己创建一个UserServiceImpl实例,自行进行对象的定制化处理
        UserService userService = new UserServiceImpl();
        //......
        return userService;
    }

}

第四步:我们在applicationContext.xml文件中配置相应的信息.

<!--userServiceXmlFactoryBean工厂bean,用于创建userServiceImpl这个bean-->
<bean id="userServiceXmlFactoryBean" name="userServiceXmlFactoryBean" class="com.minesoft.tutorial.factorybean.UserServiceXmlFactoryBean" />
<!--userServiceImpl这个bean-->
<bean id="userService" name="userService" class="com.minesoft.tutorial.service.UserServiceImpl"
      scope="singleton"
      autowire="byType"
      abstract="false"
      lazy-init="true"
      factory-bean="userServiceXmlFactoryBean"
      factory-method="createUserService"
/>

完成上述的步骤之后,我们运行一下下面的代码片段

XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
UserService userService = beanFactory.getBean(UserService.class);
User user = userService.findUserById(100L);
System.out.println(JSONObject.toJSONString(user));

说明UserServiceImpl这个bean是由我们自己创建的(由UserServiceXmlFactoryBean的createUserService方法创建),而不是由beanFactory创建的。

[2]基于注解方式,由开发者自己创建bean对象然后委托给spring容器管理

第一步:创建一个User实体类

@Data
@NoArgsConstructor
@ToString
@EqualsAndHashCode
public class User implements Serializable {

    private static final long serialVersionUID = 4800166777883697833L;

    private Long id;
    private String name;
    private String identity;
    private String mobile;
    private String bankcard;
    private Integer age;
    private Integer gender;

}

第二步:我们创建一个接口和接口实现类

public interface UserService {

    User findUserById(Long id);

}

public class UserServiceImpl implements UserService {

    @Override
    public User findUserById(Long id) {

        User user = new User();
        user.setId(id);
        user.setName("张山");
        user.setIdentity("张山");
        user.setBankcard("36457736355363");
        user.setMobile("16752652625");
        user.setGender(2);
        user.setAge(18);

        return user;
    }

}

第三步:然后关键步骤来了,我们创建一个工厂bean用于创建UserServiceImpl实例

@Component
public class UserServiceAutowiredFactoryBean implements FactoryBean {

    @Override
    public Object getObject() throws Exception {
        //开发者自己创建一个UserServiceImpl实例,自行进行对象的定制化处理
        UserService userService = new UserServiceImpl();
        //......
        return userService;
    }

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

    @Override
    public boolean isSingleton() {
        return false;
    }

}

第四步:最后我们在applicationContext.xml文件中配置相应的信息.

<context:component-scan base-package="com.minesoft.tutorial" />

完成上述的步骤之后,我们运行一下下面的代码片段

XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
UserService userService = beanFactory.getBean(UserService.class);
User user = userService.findUserById(100L);
System.out.println(JSONObject.toJSONString(user));

说明UserServiceImpl这个bean是由我们自己创建的(由UserServiceAutowiredFactoryBean的getObject创建),而不是由beanFactory创建的。

特别注意:下面的两个配置不能同时存在,spring会报存在两个bean而无法启动成功的错误

<!--userServiceXmlFactoryBean工厂bean,用于创建userServiceImpl这个bean-->
<bean id="userServiceXmlFactoryBean" name="userServiceXmlFactoryBean" class="com.minesoft.tutorial.factorybean.UserServiceXmlFactoryBean" />
<!--userServiceImpl这个bean-->
<bean id="userService" name="userService" class="com.minesoft.tutorial.service.UserServiceImpl"
      scope="singleton"
      autowire="byType"
      abstract="false"
      lazy-init="true"
      factory-bean="userServiceXmlFactoryBean"
      factory-method="createUserService"
/>

<context:component-scan base-package="com.minesoft.tutorial" />

大叔格言: 人生就如同一场攀登,每个人只需要尽自己所能攀到尽可能的高点即可,可以与人同行一路,却不可与他人攀比。

beanfactory篇-(四)FactoryBean的基本使用-九零后大叔的技术博客

更多知识请关注公众号

继续阅读
weinxin
资源分享QQ群
本站是一个IT技术分享社区, 会经常分享资源和教程; 分享的时代, 请别再沉默!
沙海
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: