public voidject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
集合checkedElements=this.checkedElements;
//带注释的方法或属性列表
迭代集合元素=
(checkedElements!=null ?checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement 元素: elementsToIterate) {
element.inject(目标, beanName, pvs);
}
}
}
循环调用使用先前注释的方法或属性构造的对象AutowiredFieldElement#inject 和AutowiredMethodElement#inject。
/**
构造处理对象的属性上有注释。
*/
私有类AutowiredFieldElement 扩展InjectionMetadata.InjectedElement {
我想要一个私有的最终布尔值。
缓存私有易失性布尔值。
@可为空
私有易失性对象cachedFieldValue;
public AutowiredFieldElement(field 字段,需要布尔值) {
超级(字段,空);
this.required=必需;
}
@覆盖
protected voidject(Object Bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//获取属性名称
字段字段=(字段) this.member;
对象的价值。
//如果bean不是单例,则重复注入操作。
if (this.cached) {
尝试{
值=solvedCachedArgument(beanName, this.cachedFieldValue);
}
catch (NoSuchBeanDefinitionException ex) {
//缓存参数的目标bean 被意外删除- 重新解析
值=solveFieldValue(字段, Bean, BeanName);
}
}
除此之外{
//第一次创建时填充这个方法
值=solveFieldValue(字段, Bean, BeanName);
}
如果(值!=null){
//如果该属性不是公共的,则将其设置为可访问的属性
ReflectionUtils.makeAccessible(field);
field.set(Bean, 值);
}
}
@可为空
私有对象replaceFieldValue(字段字段,对象bean,@Nullable String beanName){
//构造DependencyDescriptor对象
依赖描述符描述=新的依赖描述符(field, this.required);
desc.setContainingClass(bean.getClass());
//注入的Bean 数量。 字段可能是一个列表
设置autowiredBeanNames=new LinkedHashSet(1)。
Assert.state(beanFactory !=null, “没有可用的BeanFactory”);
//获取beanFactory类型转换类
TypeConverter typeConverter=beanFactory.getTypeConverter();
对象的价值。
尝试{
//查找依赖项
value=beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
抛出新的UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
已同步(此){
if (!this.cached) {
对象缓存字段值=null;
if (值!=null || this.required) {
缓存字段值=描述;
//填写依赖关系
registerDependentBeans(beanName, autowiredBeanNames);
//判断是否只有一个注入依赖
if (autowiredBeanNames.size()==1) {
String autowiredBeanName=autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName)
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
queuedFieldValue=新的ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
this.cachedFieldValue=缓存字段值;
this.cached=true;
}
}
返回值;
}
}
/**
构造处理对象的方法上有注释
*/
私有类AutowiredMethodElement 扩展InjectionMetadata.InjectedElement {
我想要一个私有的最终布尔值。
缓存私有易失性布尔值。
@可为空
私有易失性对象[]缓存方法参数;
public AutowiredMethodElement(方法方法,需要布尔值,@Nullable PropertyDescriptor pd) {
超级(方法,pd);
this.required=必需;
}
@覆盖
protected voidject(Object Bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//检查该属性是否之前已插入。如果main值为true,则不会进行二次覆盖。
if (checkPropertySkipping(pvs)) {
返回;
}
方法方法=(方法) this.member;
对象[]参数;
if (this.cached) {
尝试{
参数=solveCachedArguments(beanName);
}
catch (NoSuchBeanDefinitionException ex) {
//缓存参数的目标bean 被意外删除- 重新解析
参数=solveMethodArguments(方法, Bean, BeanName);
}
}
除此之外{
//第一次创建时填充这个方法
参数=solveMethodArguments(方法, Bean, BeanName);
}
if(参数!=null){
尝试{
//如果该属性不是公共的,则将其设置为可访问的属性
ReflectionUtils.makeAccessible(方法);
//调用方法并传递参数
method.invoke(Bean, 参数);
}
catch (InvokingTargetException ex) {
抛出ex.getTargetException()。
}
}
}
@可为空
私有对象[]solveCachedArguments(@Nullable String beanName) {
Object[] 缓存方法参数=this.cachedMethodArguments;
if (cachedMethodArguments==null) {
返回空值。
}
Object[] 参数=new Object[cachedMethodArguments.length];
for (int i=0; i argument.length; i++) {
Argument[i]=solvedCachedArgument(beanName, cachedMethodArguments[i]);
}
返回参数。
}
@可为空
private Object[]solveMethodArguments(方法方法,对象bean,@Nullable String beanName) {
//get方法有一些参数
int argumentCount=method.getParameterCount();
对象[]参数=新对象[参数计数];
依赖描述符[]描述符=新的依赖描述符[参数计数];
设置autowiredBeans=new LinkedHashSet(argumentCount);
Assert.state(beanFactory !=null, “没有可用的BeanFactory”);
TypeConverter typeConverter=beanFactory.getTypeConverter();
for (int i=0; i argument.length; i++) {
//方法参数。通过从方法参数获取i 来构造MethodParameter 对象。
MethodParameter methodParam=new MethodParameter(方法, i);
依赖描述符currDesc=new 依赖描述符(methodParam, this.required);
currDesc.setContainingClass(bean.getClass());
描述符[i]=currDesc;
尝试{
//获取方法中i参数的内容
对象arg=beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
if (arg==null !this.required) {
参数=空;
休息;
}
参数[i]=参数;
}
catch (BeansException ex) {
抛出新的UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
}
}
已同步(此){
if (!this.cached) {
if(参数!=null){
依赖描述符[]缓存方法参数=Arrays.copyOf(descriptor, argument.length);
registerDependentBeans(beanName, autowiredBeans);
if (autowiredBeans.size()==argumentCount) {
迭代器it=autowiredBeans.iterator();
类?[] paramTypes=method.getParameterTypes();
for (int i=0; i paramTypes.length; i++) {
String autowiredBeanName=it.next();
if (beanFactory.containsBean(autowiredBeanName)
beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
queuedMethodArguments[i]=new ShortcutDependencyDescriptor(
描述符[i],autowiredBeanName,paramTypes[i]);
}
}
}
this.cachedMethodArguments=缓存方法参数;
}
除此之外{
this.cachedMethodArguments=null;
}
this.cached=true;
}
}
返回参数。
}
}
以上就是@Autowired实现的完整流程。 可以概括如下。
PopulateBean-AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues
– 获取带注释的属性和方法来构造AutowiredFieldElement 和AutowiredMethodElement 对象,并在循环中调用注入以进行属性调用。
自动插入自定义注释。
编写抽象类代码。
com.yunlongn.common.core.autowired 包;
导入org.apache.commons.logging.Log。
导入org.apache.commons.logging.LogFactory。
导入org.springframework.beans.BeansException。
导入org.springframework.beans.PropertyValues。
导入org.springframework.beans.factory.*。
导入org.springframework.beans.factory.annotation.InjectionMetadata。
导入org.springframework.beans.factory.config.ConfigurableListableBeanFactory。
导入org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor。
导入org.springframework.core.annotation.AnnotationUtils。
导入org.springframework.core.annotation.MergedAnnotation。
导入org.springframework.core.annotation.MergedAnnotations。
导入org.springframework.lang.Nullable。
导入org.springframework.util.ReflectionUtils。
导入org.springframework.util.StringUtils。
导入java.beans.PropertyDescriptor。
导入java.lang.annotation.Annotation;
导入java.lang.reflect.*;
导入java.util.*。
导入java.util.concurrent.ConcurrentHashMap;
/**
摘要自动注入方法
@作者云鲁贡
*/
公共抽象类AbstractAnnotationBeanPostProcessor 实现InstantiationAwareBeanPostProcessor {;
私有最终SetClass?扩展注释annotationTypes=new LinkedHashSet(4);
私有最终MapString,InjectionMetadataInjectionMetadataCache=new ConcurrentHashMap(256);
protected Final Log Logger=LogFactory.getLog(getClass());
/**
待处理的annotationType对象
@return注解自定义注解
*/
公共抽象类是否扩展注释annotationType()?
AbstractAnnotationBeanPostProcessor () {
类扩展注释annotation=this.annotationType();
注释类型.add(注释);
}
@覆盖
公共对象postProcessBeforeInstantiation(Class? beanClass, String beanName) 抛出BeansException {
返回InstantiationAwareBeanPostProcessor.super.postProcessBeforeInstantiation(beanClass, beanName);
}
@覆盖
public boolean postProcessAfterInstantiation(Object Bean, String beanName) throws BeansException {
返回InstantiationAwareBeanPostProcessor.super.postProcessAfterInstantiation(bean, beanName);
}
@覆盖
公共PropertyValues postProcessProperties(PropertyValues pvs,对象Bean,字符串beanName){
InjectionMetadata 元数据=findAbstractMetadata(beanName, bean.getClass(), pvs);
尝试{
//注入数据
元数据.注入(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
扔掉原件。
}
catch(抛出的例子){
throw new BeanCreationException(beanName, “自动连线依赖注入失败”, ex);
}
返回pv。
}
private InjectionMetadata findAbstractMetadata(String beanName, Class?clazz, @Nullable PropertyValues pvs) {
String queueKey=(StringUtils.hasLength(beanName) ? beanName : clazz.getName());
InjectionMetadata 元数据=this.injectionMetadataCache.get(cacheKey);
//获取该类的InjectionMetadata是否已读取,如果已读取,则直接从缓存中检索。
if (InjectionMetadata.needsRefresh(元数据, clazz)) {
已同步(this.injectionMetadataCache){
//再检查一遍
元数据=this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(元数据, clazz)) {
if(元数据!=null){
元数据.clear(pvs);
}
元数据=buildAbstractMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, 元数据);
}
}
}
返回元数据。
}
私有InjectionMetadata buildAbstractMetadata(final Class? clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, this.annotationTypes)) {
返回InjectionMetadata.EMPTY。
}
ListInjectionMetadata.InjectedElement 元素=new ArrayList();
类?目标类=clazz;
做{
最终ListInjectionMetadata.InjectedElement currElements=new ArrayList();
//循环遍历targetClass的所有字段,执行FieldCallback逻辑(函数式编程接口,传递执行函数)
ReflectionUtils.doWithLocalFields(targetClass, 字段- {
//获取字段的Annotation注解
合并注释?
if (ann !=null) {
//判断是否为静态属性。如果是静态属性,则不会执行注入。
if (Modifier.isStatic(field.getModifiers())) {
如果(logger.isInfoEnabled()) {
logger.info(\’静态字段不支持抽象注释: \’ + field);
}
返回;
}
currElements.add(new AbstractFieldElement(field, ann));
}
});
//数据添加到数组的开头,父类的注解放在开头。
elements.addAll(0, currElements);
targetClass=targetClass.getSuperclass();
}
while (targetClass !=null targetClass !=Object.class);
返回InjectionMetadata.forElements(elements, clazz);
}
@可为空
私有MergedAnnotation? findAbstractAnnotation(AccessibleObject ao){
//将指定方法的注解合并为一个注解
MergedAnnotations 注释=MergedAnnotations.from(ao);
//循环遍历要扫描的注释。第一个注释类型被识别。
for (class? 注解类型: 扩展this.annotationTypes) {
合并注释?
if (annotation.isPresent()) {
返回注释。
}
}
返回空值。
}
@不建议
@覆盖
公共PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, 对象bean, 字符串beanName) {
返回postProcessProperties(pvs, bean, beanName);
}
@覆盖
公共对象postProcessBeforeInitialization(对象Bean,字符串beanName) 抛出BeansException {
返回InstantiationAwareBeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@覆盖
公共对象postProcessAfterInitialization(Object Bean, String beanName) 抛出BeansException {
返回InstantiationAwareBeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
最后
我们将分享一些结构化面试问题,您可以使用它们来审查和准备加薪面试。
以下是这些面试问题对应的技术点:
JVMMySQLMybatisMongoDBRedisSpringSpring bootSpring CloudKafkaRabbitMQNginx.
主要类别有:
基本Java 数据结构和算法并发编程数据库设计模式微服务消息传递中间件
i) 抛出BeansException {
返回InstantiationAwareBeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
最后
我们将分享一些结构化面试问题,您可以使用它们来审查和准备加薪面试。
以下是这些面试问题对应的技术点:
JVMMySQLMybatisMongoDBRedisSpringSpring bootSpring CloudKafkaRabbitMQNginx.
主要类别有:
基本Java 数据结构和算法并发编程数据库设计模式微服务消息传递中间件
[外部链接图像正在传输.(img-fZkbWvDL-1719186353764)]
[正在传输外部链接图像.(img-vJPQYiMa-1719186353764)]
[正在传输外部链接图像.(img-EJ31UBka-1719186353765)]
[正在传输外部链接图像.(img-HsFhYQw8-1719186353765)]
[外部链接照片正在传输中.(img-6y7Jrqia-1719186353766)]
[外部链接图像正在传输.(img-lmb9zPuB-1719186353766)]
[外部链接图片正在传输中.(img-Xdzv2g6y-1719186353766)]
[外部链接图像正在传输.(img-AmGvA6JH-1719186353767)]
[正在传输外部链接图像.(img-wNpbgPtb-1719186353767)]
# 以上从源码层面帮助实现自动插入注释的相关内容来源网,仅供参考。相关信息请参见官方公告。
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/91898.html