《手写Spring渐进式源码实践》-第三章 基于Cglib实现含构造函数的类实例化策略
本章目的:基于策略模式实现两种用于实例化对象的方法,如JDK、Cglib,并基于此方法实现含有带入参信息的构造函数的类实例化策略。
以下是源码:
public class BeanDefinition {
private Class bean;
public BeanDefinition(Class bean) {
this.bean = bean;
}
public Class getBean() {
return bean;
}
public void setBean(Class bean) {
this.bean = bean;
}
}
public interface SingletonBeanRegistry {
Object getSingleton(String beanName);
void registrySingletonBean(String name,Object singleton);
}
public abstract class AbstractAutowireCapableBeanFactory extends AbstractoryBeanFactory {
//实例化cblib的实例化策略
InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiation();
@Override
protected Object createBean(String beanName, BeanDefinition beanDefinition,Object[] args) throws BeansException {
Object bean;
try {
bean = createBeanInstance(beanDefinition,beanName,args);
} catch (Exception e) {
throw new BeansException("Instantiation of bean failed", e);
}
super.registrySingletonBean(beanName,bean);
return bean;
}
protected Object createBeanInstance(BeanDefinition beanDefinition,String beanName,Object[] args){
Constructor constructorToUse = null;
Class<?> beanClass = beanDefinition.getBean();
Constructor<?>[] declaredConstructors = beanClass.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
if(Objects.nonNull(args) && declaredConstructor.getParameterTypes().length ==args.length){
constructorToUse = declaredConstructor;
break;
}
}
return getInstantiationStrategy().instantiate(beanDefinition,beanName,constructorToUse,args);
}
public InstantiationStrategy getInstantiationStrategy() {
return instantiationStrategy;
}
}
public abstract class AbstractoryBeanFactory extends DefauleSingletonBeanRegistry implements BeanFactory{
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name,null);
}
@Override
public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name,args);
}
private <T> T doGetBean(final String name,final Object[] args){
Object singleton = getSingleton(name);
if(Objects.nonNull(singleton)){
return (T)singleton;
}
BeanDefinition beanDefinition = getBeanDefinition(name);
return (T)createBean(name,beanDefinition,args);
}
protected abstract BeanDefinition getBeanDefinition(String beanName);
protected abstract Object createBean(String beanName, BeanDefinition beanDefinition,Object[] args) throws BeansException;
}
public interface BeanDefinitionRegistry {
void beanDefinitionRegistry(String name, BeanDefinition beanDefinition);
}
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;
}
cglib实例化类,Cglib是基于ASM字节码框架实现的,后面会写一些相关的随笔。
public class CglibSubclassingInstantiation implements InstantiationStrategy{
@Override
public Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor, Object[] args) throws BeansException {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(beanDefinition.getBean());
enhancer.setCallback(new NoOp() {
@Override
public int hashCode() {
return super.hashCode();
}
});
if(Objects.isNull(ctor)){
return enhancer.create();
}
//入参是构造函数的参数类型和参数值
return enhancer.create(ctor.getParameterTypes(),args);
}
}
jdk实例化类
public class SimpleInstantiationStrategy implements InstantiationStrategy{
@Override
public Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor, Object[] args) throws BeansException {
Class clazz = beanDefinition.getBean();
try {
if(Objects.nonNull(ctor)) {
//获取该类的构造方法,getDeclaredConstructor() 只匹配精确参数类型,不会自动装箱/拆箱
return clazz.getDeclaredConstructor(ctor.getParameterTypes()).newInstance(args);
}else{
//获取无参构造
return clazz.getDeclaredConstructor().newInstance();
}
} catch (InstantiationException | IllegalAccessException | InvocationTargetException |NoSuchMethodException e) {
throw new BeansException("Failed to instantiate ["+clazz.getName()+"]",e);
}
}
}
public abstract class DefauleSingletonBeanRegistry implements SingletonBeanRegistry {
Map<String,Object> singletonObjects = new HashMap<>();
@Override
public Object getSingleton(String beanName) {
return singletonObjects.get(beanName);
}
@Override
public void registrySingletonBean(String name, Object singleton) {
singletonObjects.put(name,singleton);
}
}
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry{
private Map<String,BeanDefinition> beanDefinitionMap = new HashMap<>();
@Override
protected BeanDefinition getBeanDefinition(String beanName) {
try {
return beanDefinitionMap.get(beanName);
} catch (Exception e) {
throw new BeansException( "No bean named "+beanName+" is deined");
}
}
@Override
public void beanDefinitionRegistry(String name, BeanDefinition beanDefinition) {
beanDefinitionMap.put(name,beanDefinition);
}
}
public class BeansException extends RuntimeException{
public BeansException(String msg){
super(msg);
}
public BeansException(String msg,Throwable cause){
super(msg,cause);
}
}
单元测试的类:
public class UserService {
private String name;
public UserService(String name) {
this.name = name;
}
public void queryUserInfo(){
System.out.println("查询用户信息:"+name);
}
}
@SpringBootTest(classes = MyApplication.class)
public class ApiTest {
@Test
public void test_BeanFactory(){
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.beanDefinitionRegistry("userService", new BeanDefinition(UserService.class));
//第一次获取bean对象
UserService userService = (UserService)beanFactory.getBean("userService","Charlie");
userService.queryUserInfo();
}
}
源码地址:https://github.com/Charlie-pang-sys/WeaponSystem/tree/master/Java/Spring-Tutorials/spring-step-03