文章源自JAVA秀-https://www.javaxiu.com/19871.html
回顾:通过前面一个章节的了解,我们学会了bean的lookup-method和replace-method这个两个重要属性的用法。那么本章节,我们学习一个工作中使用不太频繁的一个属性,也就是factoryBean属性。文章源自JAVA秀-https://www.javaxiu.com/19871.html
文章源自JAVA秀-https://www.javaxiu.com/19871.html
1. factoryBean的基本概念介绍
我们观察前面的业务bean对象的创建,直接通过beanFactory或者applicationContext对象的getBean方法就获取到了,不像我们平时使用的new UserServiceImpl()方法,也不像我们平时使用的通过反射的getInstance方法获取到的,整个创建业务对象的过程对于开发者而言就是一个黑盒。本章节我们暂时不考虑业务对象是如何创建的(先提前泄露一下答案:绝大部分都是通过反射创建的,但是spring也留下了允许开发者自己创建bean的口子),那么如果我有一个需求,我想bean的创建由开发者自己掌握(也就是由开发者自己写代码,即new UserServiceImpl()方式去创建一个bean),而不是委托给spring容器去创建,是否可以呢?强大的spring框架是支持这一点的,怎么支持的?就是通过就是FactoryBean扩展机制实现的。文章源自JAVA秀-https://www.javaxiu.com/19871.html
2. factoryBean的基本使用
鉴于spring的几乎所有功能都存在xml配置和注解两种方式来使用,那么本章的内容将两种方式都进行讲解。
[1]基于xml方式,由开发者自己创建bean对象然后委托给spring容器管理文章源自JAVA秀-https://www.javaxiu.com/19871.html
第一步:创建一个User实体类文章源自JAVA秀-https://www.javaxiu.com/19871.html
@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;
}
第二步:我们创建一个接口和接口实现类文章源自JAVA秀-https://www.javaxiu.com/19871.html
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实例文章源自JAVA秀-https://www.javaxiu.com/19871.html
public class UserServiceXmlFactoryBean {
public UserService createUserService() {
//开发者自己创建一个UserServiceImpl实例,自行进行对象的定制化处理
UserService userService = new UserServiceImpl();
//......
return userService;
}
}
第四步:我们在applicationContext.xml文件中配置相应的信息.文章源自JAVA秀-https://www.javaxiu.com/19871.html
<!--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"
/>
完成上述的步骤之后,我们运行一下下面的代码片段文章源自JAVA秀-https://www.javaxiu.com/19871.html
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创建的。文章源自JAVA秀-https://www.javaxiu.com/19871.html
[2]基于注解方式,由开发者自己创建bean对象然后委托给spring容器管理文章源自JAVA秀-https://www.javaxiu.com/19871.html
第一步:创建一个User实体类文章源自JAVA秀-https://www.javaxiu.com/19871.html
@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;
}
第二步:我们创建一个接口和接口实现类文章源自JAVA秀-https://www.javaxiu.com/19871.html
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实例文章源自JAVA秀-https://www.javaxiu.com/19871.html
@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文件中配置相应的信息.文章源自JAVA秀-https://www.javaxiu.com/19871.html
<context:component-scan base-package="com.minesoft.tutorial" />
完成上述的步骤之后,我们运行一下下面的代码片段文章源自JAVA秀-https://www.javaxiu.com/19871.html
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创建的。文章源自JAVA秀-https://www.javaxiu.com/19871.html
特别注意:下面的两个配置不能同时存在,spring会报存在两个bean而无法启动成功的错误文章源自JAVA秀-https://www.javaxiu.com/19871.html
<!--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" />
文章源自JAVA秀-https://www.javaxiu.com/19871.html
大叔格言: 人生就如同一场攀登,每个人只需要尽自己所能攀到尽可能的高点即可,可以与人同行一路,却不可与他人攀比。文章源自JAVA秀-https://www.javaxiu.com/19871.html
文章源自JAVA秀-https://www.javaxiu.com/19871.html
文章源自JAVA秀-https://www.javaxiu.com/19871.html
更多知识请关注公众号文章源自JAVA秀-https://www.javaxiu.com/19871.html

评论