声明: 以下仅作为个人笔记:
spring中说的高大上的依赖注入: 通俗说是:
一个bean : 一个java类:
类中依赖了很多属性:
属性理解为: 另一个类 : 需要实例化的类
例如:
public class User {
private Grade grade;
//暂时未设置setter方法
}
标签配置:
<bean id="" class="user类路径(能够根据这个路径寻找到User.class)">
一个Bean的原生定义:
Bean的对象实例 : 无法区分属性 : 采用 Object beanInstance;
Bean的类名称 : 字符串类型 : 名称可以称为是一个通用属性 :
使用它: 增加了bean的前后置增强处理; 方便操作: 比如获取类名称时直接获取就可以; 不用通过Class的对象再去getSimpleName(); 多花了点代码,又多花了点时间的感觉;????
Bean的Class类对象 : Class 属性 : 根据这个属性 : 可以搞定该类的 构造器、 字段属性、 成员方法等等的操作
Bean的依赖属性定义: 因为会依赖多个, 所以定义为List<PropertyValue>
那么属性定义呢? Property Value: 定义为 :
一个名字 name : 这个是说的如果是基本数据类型属性的情况
一个值 value : 那么直接就用一个值可以设置到该类的属性中;
例外: 如果是引用数据类型 : 例如 : user依赖了Grader的时候,
那么需要先实例化Grade;
使用了ref属性
下面贴上代码:
/**
* @ClassName BeanFactoryAware
* @Description beanFactoryAware 设置了 BeanFactory : 所以它拥有了 BeanFactory的全部功能
* 实现该接口 : 随便定义一个方法中的引用属性, 那么就具有了好多的功能;
* 实现该接口 : 随便定义一个方法中的引用属性, 那么就具有了好多的功能;
* 实现该接口 : 随便定义一个方法中的引用属性, 那么就具有了好多的功能;
* 实现该接口 : 随便定义一个方法中的引用属性, 那么就具有了好多的功能;
* 实现该接口 : 随便定义一个方法中的引用属性, 那么就具有了好多的功能;
不是随便定义 : 至少拥有成员BeanFactory : 这个是一个顶层接口 : bean操作都在这了:
定位 --》 加载--》 初始化(注册)初始化到IOC容器中
* @Author dudu
* @Date 2019/7/12 9:54
* @Version 1.0
*/
public interface BeanFactoryAware {
void setBeanFactory(BeanFactory beanFactory) throws Exception;
}
/**
* 为 BeanDefinition的 实例对象 bean 设置属性值
* @param bean
* @param beanDefinition
*/
protected void applyPropertyValues(Object bean, BeanDefinition beanDefinition) throws Exception {
if(bean instanceof BeanFactoryAware) {
// bean的增强 Aware 接口
((BeanFactoryAware)bean).setBeanFactory(this);
}
//遍历 已经读取到的PropertyValues属性 , 进行自动装配 自动注入
for (PropertyValue propertyValue : beanDefinition.getPropertyValues().getPropertyValueList()) {
//获取属性值
Object value = propertyValue.getValue();
//如果是 ref 引用的 待注入的属性
if(value instanceof BeanReference) {
BeanReference reference = (BeanReference) value;
//getBean : 其实就是 创建 : 初始化 : 实例化 : 单例化的过程
value = getBean(reference.getName());
}
//实例化完成了 : 依赖属性完成
//反射设置到原装类中
try {
//bean.getClass() : 表示 : 类实例对象
//获取方法名称
//获取参数类型 : 其实就是 property标签的value的类型
//寻找到了要设置属性的setter方法
Method setMethod = bean.getClass().getDeclaredMethod(
"set" + propertyValue.getName().substring(0,1).toUpperCase()
+ propertyValue.getName().substring(1),
value.getClass());
//设置方法是可以访问的
setMethod.setAccessible(true);
//反射调用 : 为类实例中的 : set方法设置属性值 : 其实就是依赖注入
setMethod.invoke(bean, value);
} catch (Exception e){
//如果出现异常, 那么就进行字段的设置值 : 异常的情况是 : 没有set方法
Field field = bean.getClass().getDeclaredField(propertyValue.getName());
field.setAccessible(true);
field.set(bean, value);
//继续处理下一个依赖属性
continue;
}
}
}
随便贴上一张图 : 理解缓存吧!!!!!!!!!!!!!!!
定位 加载 注册