上回书说到Spring 实现Bean定义/注册/创建的一个流程,但在创建的时候其实埋了个坑,今天这回书,就把这个坑填掉!
主要就是在实例化这个过程,只是草率的使用class.newInstance();
但其实这个方法已经被废弃掉了,因为这个方法必须要有无参构造方法,所以很不灵活.
所以今天就来重写一下获取实例化的方法.
BeanFactory
首先因为每个Bean的构造函数是不固定的,所以可以用这个方式来扩展一下getBean()
public interface BeanFactory {
Object getBean(String name,Object... args);
}
AbstractBeanFactory
这里只要是改造了createBean添加了参数
然后就是去改造实现类AbstractBeanFactory
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {
@Override
public Object getBean(String beanName,Object... args){
//继承自DefaultSingletonBeanRegistry 的方法
Object bean = getSingleton(beanName);
if (bean != null){
return bean;
}
//获取不到就两个抽象方法 让实现此类的去做实现
BeanDefinition beanDefinition = getBeanDefinition(beanName);
return createBean(beanName,beanDefinition,args);
}
protected abstract BeanDefinition getBeanDefinition(String name) throws BeansException;
//添加参数
protected abstract Object createBean(String beanName,BeanDefinition bean,Object... args) throws BeansException;
}
AbstractAutowireCapableBeanFactory
然后对实现这个createBean的类也小改造一下,主要是加了个实例化的方法来取代原来简单的实例化
@Getter
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory{
private InstantiationStrategy instantiationStrategy =new CglibSubclassingInstantiationStrategy();
@Override
protected Object createBean(String name, BeanDefinition beanDefinition,Object[] args) throws BeansException {
Object bean;
bean = createBeanInstance(name,beanDefinition,args);
addSingletonBean(name,bean);
return bean;
}
protected Object createBeanInstance(String name, BeanDefinition beanDefinition,Object[] args){
Constructor constructor =null;
Class beanClass = beanDefinition.getBeanClass();
//获取所有的构造方法
Constructor[] declaredConstructors = beanClass.getDeclaredConstructors();
//简单对比 选择构造类型 spring还会对比类型
for (Constructor ctor : declaredConstructors) {
if (null!=args && ctor.getParameterTypes().length ==args.length){
constructor=ctor;
break;
}
}
//创建
return getInstantiationStrategy().instantiate(beanDefinition,name,constructor,args);
}
}
InstantiationStrategy
提供一个抽象方法,目的是根据提供的参数进行实例化
public interface InstantiationStrategy {
Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor,Object[] args) throws BeansException;
}
这里提供了两种实现方式
SimpleInstantiationStrategy
简易版
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 (null!=ctor){
return clazz.getDeclaredConstructor(ctor.getParameterTypes()).newInstance(args);
}else {
//无参构造
return clazz.getDeclaredConstructor().newInstance();
}
}catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e){
throw new BeansException("Failed to instantiate [" + clazz.getName() + "]", e);
}
}
}
CglibSubclassingInstantiationStrategy
不过Spring更喜欢用Cglib
public class CglibSubclassingInstantiationStrategy 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 (null == ctor)return enhancer.create();
return enhancer.create(ctor.getParameterTypes(),args);
}
}
最后开始测试
@Test
public void testBeanFactory(){
//初始化 beanFactory
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
//创建 bean信息
BeanDefinition beanDefinition = new BeanDefinition(UserService.class);
String beanName = "userService";
//注册到工厂中
beanFactory.registerBeanDefinition(beanName,beanDefinition);
//获取实例
UserService userService = (UserService) beanFactory.getBean(beanName,"小明");
userService.queryUserInfo();
}
应该是addBeanPostProcessor()实现的方式不对,之前代码不完整,所以少了这块自己补的, 现在出问题了, 因为我之前暂时填了那个坑, 走向bean注册, 这样会导致的结果就是里面携带的参数丢失了.
所以去看一下人家源码怎么实现的,然后改造了一下!
这次直接把后处理器管理起来,这样就走得通了.
AbstractBeanFactory
package com.linnine.spring.beans.factory.support;
import com.linnine.spring.beans.BeansException;
import com.linnine.spring.beans.factory.config.BeanDefinition;
import com.linnine.spring.beans.factory.config.BeanPostProcessor;
import com.linnine.spring.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.util.Assert;
import java.util.ArrayList;
import java.util.List;
//09 从实现BeanFactory改成实现ConfigurableBeanFactory
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements ConfigurableBeanFactory {
//09新增 管理后处理器 源码的获取不是通过new这个, 这里临时用一下
private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();
public Object getBean(String beanName,Object... args){
//继承自DefaultSingletonBeanRegistry 的方法
Object bean = getSingleton(beanName);
if (bean != null){
return bean;
}
//获取不到就两个抽象方法 让实现此类的去做实现
BeanDefinition beanDefinition = getBeanDefinition(beanName);
return createBean(beanName,beanDefinition,args);
}
protected abstract BeanDefinition getBeanDefinition(String name) throws BeansException;
//添加参数
protected abstract Object createBean(String beanName,BeanDefinition bean,Object... args) throws BeansException;
//09 改造
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
this.beanPostProcessors.remove(beanPostProcessor);
this.beanPostProcessors.add(beanPostProcessor);
}
//09 转移 原本的获取改成从这里获取
public BeanPostProcessor[] getBeanPostProcessors(){
return this.beanPostProcessors.toArray(new BeanPostProcessor[0]);
}
}
ConfigurableBeanFactory
之前一直没用到,现在也用到了
import com.linnine.spring.beans.factory.BeanFactory;
//09 改成接口 实现BeanFactory
public interface ConfigurableBeanFactory extends BeanFactory {
//09 添加一个接口方法
void addBeanPostProcessor(BeanPostProcessor var1);
}
ConfigurableListableBeanFactory
//09 多实现了后面两个
public interface ConfigurableListableBeanFactory extends ListableBeanFactory, AutowireCapableBeanFactory,ConfigurableBeanFactory {
void preInstantiateSingletons();
//09去除添加后处理器的方法
BeanDefinition getBeanDefinition(String name);
void destroySingletons();
}
DefaultListableBeanFactory
也是去除了之前自己的暂时实现方法
这样就能通了
执行:init-method
ClassLoader:jdk.internal.loader.ClassLoaders$AppClassLoader@2c13da15
Bean Name is:userService
执行:UserService.afterPropertiesSet
测试结果:小傅哥10001腾讯深圳
ApplicationContextAware:com.linnine.spring.context.support.ClassPathXmlApplicationContext@304bb45b
BeanFactoryAware:com.linnine.spring.beans.factory.support.DefaultListableBeanFactory@723ca036
执行:destroy-method
执行:UserService.destroy
但是 不是很能理解为什么把beanPostProcessors放在AbstractBeanFactory里面管理