目标
实现有参构造函数实例化对象.
设计
参考Spring Bean的容器源码实现方式, 在BeanFactory中添加Object getBean(String name, Object... args)
创建有参构造bean对象的两种方式
- 基于jdk的DeclaredConstructor
- 使用Cglib 动态创建Bean对象
uml图如下 BeanFactory 类新增getBean方法, 该方法有可变参数的构造. AbstractAutowireCapableBeanFactory 对象, 创建bean的入参改为可接收多个数组参数. 依赖创建实例的策略接口 InstantiationStrategy, 该策略接口由两个实现类 CglibSubclassInstantiationStrategy 和 SimpleInstantiationStrategy 分别是基于Cglib和jdk的创建对象.
实现
新增getBean接口
public interface BeanFactory {
Object getBean(String name) 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();
for (Constructor<?> ctor : declaredConstructors) {
if (null != args && ctor.getParameterTypes().length == args.length) {
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() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
BeanDefinition beanDefinition = new BeanDefinition(UserService.class);
beanFactory.registerBeanDefinition("userService", beanDefinition);
UserService userService = (UserService) beanFactory.getBean("userService", "周杰伦");
userService.queryUserInfo();
}
测试结果如下
查询用户信息: 周杰伦
测试无构造函数的
@Test
public void test_noArgsNewInstance() throws IllegalAccessException, InstantiationException {
UserService userService = UserService.class.newInstance();
System.out.println(userService);
}
测试有构造函数实例化
@Test
public void test_constructor() throws Exception {
Class<UserService> userServiceClass = UserService.class;
Constructor<UserService> declaredConstructor = userServiceClass.getDeclaredConstructor(String.class);
UserService userService = declaredConstructor.newInstance("周杰伦");
System.out.println(userService);
}
获取构造函数信息
@Test
public void test_parameterTypes() throws Exception {
Class<UserService> beanClass = UserService.class;
Constructor<?>[] declaredConstructors = beanClass.getDeclaredConstructors();
Constructor<?> constructor = null;
for (Constructor<?> ctor : declaredConstructors) {
if (ctor.getParameterTypes().length == 1) {
constructor = ctor;
break;
}
}
Constructor<UserService> declaredConstructor = beanClass.getDeclaredConstructor(constructor.getParameterTypes());
UserService userService = declaredConstructor.newInstance("周杰伦");
System.out.println(userService);
}
测试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);
}
测试Cglib的策略实例化
@Test
public void test_cglibSubclassInstantiationStrategy() throws Exception {
InstantiationStrategy instantiationStrategy = new CglibSubclassInstantiationStrategy();
BeanDefinition beanDefinition = new BeanDefinition(UserService.class);
Class<UserService> userServiceClass = UserService.class;
Constructor<UserService> declaredConstructor = userServiceClass.getDeclaredConstructor(String.class);
Object obj = instantiationStrategy.instantiate(beanDefinition, "userService" , declaredConstructor, new Object[]{"周杰伦"});
System.out.println(obj);
}
|