Spring 依赖注入模式和类型

本文内容如有错误、不足之处,欢迎技术爱好者们一同探讨,在本文下面讨论区留言,感谢。欢迎转载,转载请注明出处(https://blog.csdn.net/feng_xiaoshi/article/details/105799771),谢谢。

简介

依赖注入主要有两种模式,手动模式和自动模式,自动模式又叫做 Autowiring(自动绑定),官方不推荐使用自动模式。

手动模式

通过配置或者编程的方式,提前安排注入规则:

  • XML 资源配置元信息
  • Java 注解配置元信息
  • API 配置元信息

通常开发过程中较常使用的是 XML配置和 Java 注解配置,API配置不常使用,API配置通常是给容器开发者或者Spring扩展使用。
事实上 XML 配置和 Java 注解配置就依赖于 API 配置的操作。

自动模式

实现方提供依赖自动关联的方式,按照内建的注入规则,专业术语叫 Autowiring ,Spring 容器能够通过自动绑定的关系,在合作 Bean 之间(依赖类和被依赖类)将 Bean 和 Bean 之间的相互依赖关系(组合或关联),处理和合作者的关系。这里的合作者不一定是 Bean ,也可能是资源。Autowiring 可以减少参数或者构造器配置参数。

自动模式的几种类型
类型说明
no默认值,未激活,需要手动指定依赖注入对象
byName根据被注入属性的名称作为 Bean 名称进行依赖查找,并将对象设置到该属性
byType根据被注入属性的类型作为依赖类型进行查找,并将对象设置到该属性
constructor特殊的 byType 类型,用于构造器参数

Spring 中 Autowire 枚举就是上面集大成者:

public enum Autowire {

	/**
	 * Constant that indicates no autowiring at all.
	 */
	NO(AutowireCapableBeanFactory.AUTOWIRE_NO),

	/**
	 * Constant that indicates autowiring bean properties by name.
	 */
	BY_NAME(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME),

	/**
	 * Constant that indicates autowiring bean properties by type.
	 */
	BY_TYPE(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE);

	// 这里为什么没有出现构造器呢! 因为它是特殊的 byType

	private final int value;


	Autowire(int value) {
		this.value = value;
	}

	public int value() {
		return this.value;
	}

	/**
	 * Return whether this represents an actual autowiring value.
	 * @return whether actual autowiring was specified
	 * (either BY_NAME or BY_TYPE)
	 */
	public boolean isAutowire() {
		return (this == BY_NAME || this == BY_TYPE);
	}
}

Autowire引用了 AutowireCapableBeanFactory 类,具有自动绑定功能的 BeanFactory,通过名字就可以判断出继承了 BeanFactory。

public interface AutowireCapableBeanFactory extends BeanFactory {

	int AUTOWIRE_NO = 0;

	int AUTOWIRE_BY_NAME = 1;

	int AUTOWIRE_BY_TYPE = 2;

	int AUTOWIRE_CONSTRUCTOR = 3;

	// 自动探测 Spring 3 以前遗留的
	@Deprecated
	int AUTOWIRE_AUTODETECT = 4;

	String ORIGINAL_INSTANCE_SUFFIX = ".ORIGINAL";


	<T> T createBean(Class<T> beanClass) throws BeansException;

	void autowireBean(Object existingBean) throws BeansException;

	Object configureBean(Object existingBean, String beanName) throws BeansException;

	Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;


	Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;

	void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
			throws BeansException;
			
	void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;

	Object initializeBean(Object existingBean, String beanName) throws BeansException;

	Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException;

	Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException;

	void destroyBean(Object existingBean);


	<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;

	Object resolveBeanByName(String name, DependencyDescriptor descriptor) throws BeansException;

	@Nullable
	Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;

	@Nullable
	Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;

}

自动配置的缺陷

自动配置是一种猜测性的技术,或者说是半猜测的技术,通过关联,容器会根据名称、类型、构造方法进行查找相同的进行一个关联,因此就会产生一个问题:Spring 会非常关注这个查找的精确性,如果出现一些模糊的情况,比如说名称取得不对,这样就会出现一个不确定的结果。

依赖注入类型
依赖注入类型配置元数据
Setter 方法< proeprty name=“user” ref=“userBean”/>
构造器< constructor-arg name=“user” ref=“userBean”/>
字段@Autowired User user;
方法@Autowired public void user(User user){…}
接口回调class MyBean implements BeanFactoryAware{…}

Setter 方法通过方法注入,构造器通过构造器参数来进行传递,字段注入在 XML 配置中没有方法可以实现,Setter 注入是通过一个 Set 方法来实现参数绑定或者关联到数据,XML 配置是通过调用 Set 方法,通过反射的方式来进行调用,字段注入是直接把这个参数注入到字段,其实 Spring 官方是不想采纳这种实现方式。接口回调通过显示的传递 BeanFactory 给你的接口进行回调。

Autowire 是通过静态上下文绑定,因为在动态上下文中,Spring 很难判断Bean 是不是已经在上下文中,无法确保整个 classpath 上所有的包是不是都少建了,由于没有运行状态因此无法进行预判。

总结

在本文中,通过依赖注入的模式和类型方面,讨论了不同注入的不同点和相同点。以及使用自动注入时需要注意的地方。

参考资料

Spring 依赖注入(DI) 的三种方式 和 对集合类型的注入

spring的IOC——依赖注入的两种实现类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值