文章目录
目标
- 目标
- 设计
- 实现
- 新增getBean接口
- 定义实例化策略接口
- JDK 实例化
- Cglib 实例化
- 创建策略调用
- 测试
- 测试有参的构造实例创建
- 测试无构造函数的
- 测试有构造函数实例化
- 获取构造函数信息
- 测试Cglib实例化
- 测试Cglib的策略实例化
实现有参构造函数实例化对象.
设计参考Spring Bean的容器源码实现方式, 在BeanFactory中添加Object getBean(String name, Object... args)
创建有参构造bean对象的两种方式
- 基于jdk的DeclaredConstructor
- 使用Cglib 动态创建Bean对象
uml图如下 BeanFactory 类新增getBean方法, 该方法有可变参数的构造. AbstractAutowireCapableBeanFactory 对象, 创建bean的入参改为可接收多个数组参数. 依赖创建实例的策略接口 InstantiationStrategy, 该策略接口由两个实现类 CglibSubclassInstantiationStrategy 和 SimpleInstantiationStrategy 分别是基于Cglib和jdk的创建对象.
public interface BeanFactory {
Object getBean(String name) throws BeansException;
/**
* 重载多参数的getBean方法 这样可以方便的传递入参给构造函数
* @throws BeansException
*/
Object getBean(String name, Object... args) throws BeansException;
}
定义实例化策略接口
public interface InstantiationStrategy {
// 实例化策略接口
Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor, Object[] args) throws BeansException;
}
JDK 实例化
public class SimpleInstantiationStrategy implements InstantiationStrategy{
@Override
public Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor, Object[] args) throws BeansException {
Class clazz = beanDefinition.getBeanClass();
try {
if (ctor != null) {
// 有参构造的实例化
return clazz.getDeclaredConstructor(ctor.getParameterTypes()).newInstance(args);
} else {
// 无参构造的实例化
return clazz.getDeclaredConstructor().newInstance();
}
} catch (Exception e) {
e.printStackTrace();
throw new BeansException("failed to instantiate " + clazz.getName(), e);
}
}
}
判断是否为有构造函数的实例化
Cglib 实例化public class CglibSubclassInstantiationStrategy implements InstantiationStrategy {
@Override
public Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor, Object[] args) throws BeansException {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(beanDefinition.getBeanClass());
enhancer.setCallback(new NoOp() {
@Override
public int hashCode() {
return super.hashCode();
}
});
if (ctor == null) {
return enhancer.create();
}
return enhancer.create(ctor.getParameterTypes(), args);
}
}
创建策略调用
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {
private InstantiationStrategy instantiationStrategy = new CglibSubclassInstantiationStrategy();
protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException {
Object bean;
try {
// 构建对象 通过传入构造函数的入参
bean = createBeanInstance(beanDefinition, beanName, args);
} catch (Exception e) {
e.printStackTrace();
throw new BeansException("Instantiation of bean failed", e);
}
addSingleton(beanName, bean);
return bean;
}
protected Object createBeanInstance(BeanDefinition beanDefinition, String beanName, Object[] args) {
Constructor constructorToUse = null;
Class beanClass = beanDefinition.getBeanClass();
// 获取到所有的构造函数
Constructor[] declaredConstructors = beanClass.getDeclaredConstructors();
// Constructor 代表了你有多少个构造函数
for (Constructor ctor : declaredConstructors) {
if (null != args && ctor.getParameterTypes().length == args.length) {
// 循环比对出构造函数集合与入参信息 args 的匹配情况
constructorToUse = ctor;
break;
}
}
return getInstantiationStrategy().instantiate(beanDefinition, beanName, constructorToUse, args);
}
public InstantiationStrategy getInstantiationStrategy() {
return instantiationStrategy;
}
public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) {
this.instantiationStrategy = instantiationStrategy;
}
}
测试
测试的业务类
public class UserService {
private String name;
public UserService() {
}
public UserService(String name) {
this.name = name;
}
public void queryUserInfo() {
System.out.println("查询用户信息: " + name);
}
@Override
public String toString() {
return "UserService{" +
"name='" + name + '\'' +
'}';
}
}
测试有参的构造实例创建
@Test
public void test_BeanFactory() {
// 1.初始化 BeanFactory
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 3. 注入bean
BeanDefinition beanDefinition = new BeanDefinition(UserService.class);
beanFactory.registerBeanDefinition("userService", beanDefinition);
// 4.获取bean 创建对象 传递有参数的
UserService userService = (UserService) beanFactory.getBean("userService", "周杰伦");
userService.queryUserInfo();
}
测试结果如下
查询用户信息: 周杰伦
测试无构造函数的 /**
* 无参构造创建对象
* @throws IllegalAccessException
* @throws InstantiationException
*/
@Test
public void test_noArgsNewInstance() throws IllegalAccessException, InstantiationException {
UserService userService = UserService.class.newInstance();
System.out.println(userService); // UserService{name='null'}
}
测试有构造函数实例化
/**
* 有参构造创建对象
* @throws Exception
*/
@Test
public void test_constructor() throws Exception {
Class userServiceClass = UserService.class;
Constructor declaredConstructor = userServiceClass.getDeclaredConstructor(String.class);
UserService userService = declaredConstructor.newInstance("周杰伦");
System.out.println(userService); // UserService{name='周杰伦'}
}
获取构造函数信息
@Test
public void test_parameterTypes() throws Exception {
Class beanClass = UserService.class;
Constructor[] declaredConstructors = beanClass.getDeclaredConstructors();
Constructor constructor = null;
for (Constructor ctor : declaredConstructors) {
if (ctor.getParameterTypes().length == 1) {
constructor = ctor;
break;
}
}
Constructor declaredConstructor = beanClass.getDeclaredConstructor(constructor.getParameterTypes());
UserService userService = declaredConstructor.newInstance("周杰伦");
System.out.println(userService); // UserService{name='周杰伦'}
}
测试Cglib实例化
@Test
public void test_cglib() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
enhancer.setCallback(new NoOp() {
@Override
public int hashCode() {
return super.hashCode();
}
});
Object obj = enhancer.create(new Class[]{String.class}, new Object[]{"周杰伦"});
System.out.println(obj); // UserService{name='周杰伦'}
}
测试Cglib的策略实例化
@Test
public void test_cglibSubclassInstantiationStrategy() throws Exception {
InstantiationStrategy instantiationStrategy = new CglibSubclassInstantiationStrategy();
BeanDefinition beanDefinition = new BeanDefinition(UserService.class);
Class userServiceClass = UserService.class;
Constructor declaredConstructor = userServiceClass.getDeclaredConstructor(String.class);
Object obj = instantiationStrategy.instantiate(beanDefinition, "userService" , declaredConstructor, new Object[]{"周杰伦"});
System.out.println(obj); // UserService{name='周杰伦'}
}