学习笔记-Spring实战-动手实现一个小的spring-Chapter-3
1、思考
怎么处理带参数的构造函数呢?
传入,可以在获取Bean的时候把参数传入,BeanFactory的getBean方法 getBean(String name,Object …args);
怎么创建带参实例?两种 jdk反射 cglib代理技术
在那边写代码呢?(串流程)可以在创建Bean的时候 AbstractAutowireCapableBeanFactory这个里面加入逻辑
2、设计

3、实现
1、BeanFactory:
/**
*
* @param beanname
* @param args
* @return java.lang.Object
* @author LiWenQiang
* @date 2022/3/3 09:40
*/
Object getBean(String beanname,Object... args);
2、AbstractBeanFactory
@Override
public Object getBean(String beanName) {
//整合在一起
return doGetbean(beanName,null);
}
@Override
public Object getBean(String beanName, Object... args) {
return doGetbean(beanName,args);
}
protected Object doGetbean(String beanName,Object ...args){
//判断是否存在bean
final Object singleton = getSingleton(beanName);
if(singleton != null){
return singleton;
}
//获取bean定义
final BeanDefinition beanDefinition = getBeanDefinition(beanName);
return createBean(beanName,beanDefinition,args);
}
abstract protected Object createBean(String beanName, BeanDefinition beanDefinition,Object ... args);
3、AbstractAutowiredCapableBeanFactory
InstantiationStrategy instantiationStrategy = new CglibInstantionStategy();
@Override
protected Object createBean(String beanName, BeanDefinition beanDefinition, Object... args) {
Object bean = null;
//创建Bean
try {
bean = createBeanInstance(beanName,beanDefinition,args);
} catch (Exception e) {
//转换异常 并把原始异常抛出
throw new BeansException("bean create fail!",e);
}
//加入到容器
adddSingleton(beanName,bean);
return bean;
}
protected Object createBeanInstance(String beanName, BeanDefinition beanDefinition, Object[] args) {
final Constructor<?>[] declaredConstructors = beanDefinition.getBeanDefinition().getDeclaredConstructors();
Constructor c = null;
for (Constructor<?> declaredConstructor : declaredConstructors) {
if(args != null && declaredConstructor != null && declaredConstructor.getParameterTypes().length==args.length){
c = declaredConstructor;
break;
}
}
final Object beanInstance = getInstantiationStrategy().createBeanInstance(beanName, beanDefinition, c, args);
return beanInstance;
}
public InstantiationStrategy getInstantiationStrategy() {
return instantiationStrategy;
}
4、InstantiationStrategy
Object createBeanInstance(String beanName, BeanDefinition beanDefinition, Constructor constructor,Object ... args) throws BeansException;
5、CglibInstantionStategy
@Override
public Object createBeanInstance(String beanName, BeanDefinition beanDefinition, Constructor constructor, Object... args) throws BeansException {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(beanDefinition.getBeanDefinition());
enhancer.setCallback(new NoOp() {
@Override
public int hashCode() {
return super.hashCode();
}
});
if(constructor != null){
return enhancer.create(constructor.getParameterTypes(),args);
}
return enhancer.create();
}
4、验证
@Test
public void testIOC1(){
//创建IOC容器
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
//注册一个bean进去
beanFactory.registBeanDefinition("userService",new BeanDefinition(UserService.class));
//获取bean 多次获取
final UserService userService = (UserService) beanFactory.getBean("userService","111");
final UserService userService2 = (UserService) beanFactory.getBean("userService","222");
final UserService userService3 = (UserService) beanFactory.getBean("userService","333");
System.out.println(userService);
System.out.println(userService2);
System.out.println(userService3);
//调用方法测试
userService.queryUserInfo();
}
5、问题
现在注册的Bean都是没有属性的?Bean的属性怎么填充呢?
本文探讨了如何在Spring框架中实现带参数的构造函数注入,并通过具体代码演示了使用CGLIB代理技术来创建带有参数的Bean实例的过程。
867

被折叠的 条评论
为什么被折叠?



