您的位置:首页 > 游戏 > 手游 > 百度网站大全_推广普通话内容100字_知了seo_百度推广代理公司

百度网站大全_推广普通话内容100字_知了seo_百度推广代理公司

2025/1/9 10:24:53 来源:https://blog.csdn.net/qq_26437925/article/details/144796129  浏览:    关键词:百度网站大全_推广普通话内容100字_知了seo_百度推广代理公司
百度网站大全_推广普通话内容100字_知了seo_百度推广代理公司

直接用一些例子代码说明@Autorwired的工作原理,Spring版本为5.1.3 。

一般认为@Autorwired是自动注入的,但实际不是,和byName, byType等自动注入没有任何关系。

Ca & Cb & Cc 三个类

  • Ca
public class Ca {public Ca(){System.out.println("Ca()");}/*** Autowired 是手动注入*/@AutowiredCb cb;/*** autowire inject cb only if default-autowire="byType"*/public void setXxx(Cb cb) {System.out.println("byType is ok, byName is not support:" + cb);}/*** autowire inject cb only if default-autowire="byType" or "byName"*/public void setCc(Cc cc) {System.out.println("Ca Set Cc:" + cc);}public void cbOut(){System.out.println("Cb:" + cb);}
}
  • Cb
public class Cb {public Cb(){System.out.println("Cb()");}
}
  • Cc
public class Cc {public Cc(){System.out.println("Cc()");}
}

自定义一个BeanFactoryPostProcessor 打印bean信息

ModeBeanFactoryPostprocessor

public class ModeBeanFactoryPostprocessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {GenericBeanDefinition ca = (GenericBeanDefinition)beanFactory.getBeanDefinition("ca");/*** 打印 Ca 的注入模型* {@link org.springframework.beans.factory.config.AutowireCapableBeanFactory}* AUTOWIRE_NO = 0;* AUTOWIRE_BY_NAME = 1;* AUTOWIRE_BY_TYPE = 2;* AUTOWIRE_CONSTRUCTOR = 3;*/System.out.println("ca autowiring mode=" + ca.getAutowireMode() + ":" + getAutowire(ca.getAutowireMode()));}private String getAutowire(int mode) {String[] arr = {"AUTOWIRE_NO", "AUTOWIRE_BY_NAME", "AUTOWIRE_BY_TYPE", "AUTOWIRE_CONSTRUCTOR", "AUTOWIRE_AUTODETECT"};return arr[mode];}
}

default-autowire=“byName”

  • spring-autowired-by-name.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.0.xsd"default-autowire="byName"><bean id="ca" class="com.mb.autowired.Ca" scope="singleton"></bean><bean id="cb" class="com.mb.autowired.Cb" scope="singleton"></bean><bean id="cc" class="com.mb.autowired.Cc" scope="singleton"></bean><bean id="modeBeanFactoryPostProcessor" class="com.mb.autowired.ModeBeanFactoryPostprocessor"></bean></beans>

测试

@Test
public void testAutoByName() {ApplicationContext applicationContext =new ClassPathXmlApplicationContext("spring-autowired-by-name.xml");Ca ca = (Ca) applicationContext.getBean("ca");Assert.assertTrue(ca != null);ca.cbOut();
}

输出如下
在这里插入图片描述

可以看到没有Ca没有自动注入Cb,因为byName自动注入要求set方法为setCb(), 而实际为setXxxx, 不能识别

default-autowire=“byType”

  • spring-autowired-by-type.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.0.xsd"default-autowire="byType"><bean id="ca" class="com.mb.autowired.Ca" scope="singleton"></bean><bean id="cb" class="com.mb.autowired.Cb" scope="singleton"></bean><bean id="cc" class="com.mb.autowired.Cc" scope="singleton"></bean><bean id="modeBeanFactoryPostProcessor" class="com.mb.autowired.ModeBeanFactoryPostprocessor"></bean></beans>

当改成byType之后测试

@Test
public void testAutoByType() {ApplicationContext applicationContext =new ClassPathXmlApplicationContext("spring-autowired-by-type.xml");Ca ca = (Ca) applicationContext.getBean("ca");Assert.assertTrue(ca != null);ca.cbOut();
}

则输出如下
在这里插入图片描述

可以看到ca 注入cb是成功的,同时注意到@Autowired的Cb还是个null

@Autowired
Cb cb;

至少可以确认一个结论

  • @Autowired和处理byType不是同一回事

@Autowired测试

接口I,及其实现类I1, I2

public interface I {
}
@Component
public class I1 implements I {public I1(){System.out.println("I1()");}
}
@Component
public class I2 implements I {public I2(){System.out.println("I2()");}
}

Ta类

@Component
public class Ta {public Ta() {System.out.println("Ta()");}@AutowiredI i1;public I getI(){return i1;}
}

自定义BeanFactoryPostProcessor打印装配方式

@Component
public class TaBeanFactoryPostprocessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {GenericBeanDefinition ta = (GenericBeanDefinition)beanFactory.getBeanDefinition("ta");/*** 打印 Ta 的注入模型* {@link org.springframework.beans.factory.config.AutowireCapableBeanFactory}* AUTOWIRE_NO = 0;* AUTOWIRE_BY_NAME = 1;* AUTOWIRE_BY_TYPE = 2;* AUTOWIRE_CONSTRUCTOR = 3;*/System.out.println("ta autowiring mode=" + ta.getAutowireMode() + ":" + getAutowire(ta.getAutowireMode()));}private String getAutowire(int mode) {String[] arr = {"AUTOWIRE_NO", "AUTOWIRE_BY_NAME", "AUTOWIRE_BY_TYPE", "AUTOWIRE_CONSTRUCTOR", "AUTOWIRE_AUTODETECT"};return arr[mode];}
}

配置扫描类

@ComponentScan("com.mb.autowired")
@Configuration
public class TaConfig {}

如上类都是com.mb.autowired包下

AnnotationConfigApplicationContext测试代码

@Test
public void testAnnotationAutoTa() {ApplicationContext applicationContext =new AnnotationConfigApplicationContext(TaConfig.class);Ta ta = (Ta) applicationContext.getBean("ta");System.out.println("ta getI:" + ta.getI());
}

输入如下
在这里插入图片描述
可以看到:Ta是非自动装配的,但是确实是autowire了i1.

所以可以看到一个现象:

  • @Autowired可以不是自动装配的,也可以自动注入

@Autowired原理

debugta这个bean的初始化的populateBean阶段,可以看到if块直接跳过了,证明了确实是AUTOWIRE_NO
在这里插入图片描述

在populateBean的阶段会用InstantiationAwareBeanPostProcessor这个BeanPostProcessor进行处理属性

继续debug会发现AutowiredAnnotationBeanPostProcessor在这里插入图片描述

完成了注入:
在这里插入图片描述

AutowiredAnnotationBeanPostProcessor的处理方法

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata

执行了buildAutowiringMetadata方法找到@Autowire依赖,通过反射找到 ta @Autowire 了 i1
在这里插入图片描述

org.springframework.beans.factory.annotation.InjectionMetadata.InjectedElement#inject方法中可以看到使用了java的反射机制完成了filed的设置
在这里插入图片描述
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement 的 inject 方法中完成最后的注入

org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency

根据type会找到两个类型为I的bean:i1, i2
在这里插入图片描述

最后根据依赖的name取一个
在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com