你所不知道的Spring自动注入详解

自动注入和@Autowire

@Autowire不属于自动注入!

注入方式(重要)

在Spring官网上(文档),定义了在Spring中的注入方式一共有两种:set方法和构造函数。

也就是说,你想在A类里面注入另外一个B类,无论你是通过写 XML文件,或者通过 @Autowried,他们最终都是通过这个A类的set方法或者构造函数,将B类注入到A类中!

换句话说,你如果A类里面没有setB(B b){…},那你就别想通过set方法把B类注入到A类中

自动注入

首先摆出一个比较颠覆的观点:@Autowire不属于自动注入!

如果要讨论自动注入,我们先要了解什么是自动注入,什么是手动注入。

  • 手动注入:在Spring 1.x的时候,我们想要在A类中注入B类,我们只能通过在xml配置文件中,加上< property >标签。也就是说,如果我们想在A类中注入100个类,我们就要重复着写100个< property > 。而Spring为了我们能少码点字,就提供了 @Autowired 注解,通过这个注解,我们就可以更加轻松的手动注入需要的类
  • 自动注入:如果在A类里面,需要用到B类,C类等等…我不需要重复着写100个< property >或者100个@Autowired。而是只需要注明需要哪些类即可

既然是自动,那就代表我啥都不用做,就连一个 @Autowire 我都不加的情况下我让B类注入进A类,这才算真正的自动注入

证明:

首先,我们先看看最原始的,通过xml的注入类:

<bean id="exampleBean" class="examples.ExampleBean">
 <!-- setter injection using the nested ref element -->
 <property name="beanOne">
  <ref bean="anotherExampleBean"/>
 </property>
</bean>

<bean id="anotherExampleBean" class="examples.AnotherBean"/>

对应的类:

public class ExampleBean {
 private AnotherBean beanOne;

 public void setBeanOne(AnotherBean beanOne) {
  this.beanOne = beanOne;
 }
}

这是Spring官网上的一个例子,在最开始,我们通过在XML中追加<property>属性来为类加上其所需要的类。这种手动注入的方式十分的繁琐,所以后面出现了@Autowire注解来进行注入!说白了,就是人们为了偷懒,用一个@Autowire注解代替了写一大串的property属性!(先这么理解,底层源码肯定不是这么做的!)这样的话,还能说 @Autowire 是自动注入了吗?

对于自动注入,在Spring中提供了下面4种方式(甚至我可以更加负责任的告诉你们,在Spring源码中有5种)

先根据官方文档提供的4种方法进行解释:

  • no:就是不要自动装配
  • byName:通过名字进行自动装配
  • byType:通过类型进行自动装配
  • constructor:通过构造函数进行自动装配

最开始我有写到,在Spring中,自动注入的方式就只有两种,通过set()方法和构造函数。所以 byName和 byType 都是通过 set()进行装配的。



代码演示:通过byType方式进行自动注入

通过在<beans>标签的末尾加上 default-autowire="byType"来实现Spring的自动注入

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	  xsi:schemaLocation="http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"
		default-autowire="byType">

	<bean id="defaultAutowireService" class="com.spring.autowiringModes.DefaultAutowireService">
	</bean>

	<bean id="byTypeDemo" class="com.spring.autowiringModes.ByTypeDemo"/>

</beans>

Java类:

public class DefaultAutowireService {
	ByTypeDemo byTypeDemo;

	public ByTypeDemo getByTypeDemo() {
		return byTypeDemo;
	}

	public void setByTypeDemo(ByTypeDemo byTypeDemo) {
		this.byTypeDemo = byTypeDemo;
	}
}

启动类:

public class XmlTest {
	public static void main(String[] args) {

		ClassPathXmlApplicationContext context =
				new ClassPathXmlApplicationContext("spring.xml");

		DefaultAutowireService bean =
				context.getBean("defaultAutowireService", DefaultAutowireService.class);

		System.out.println(bean.getByTypeDemo());

	}
}

控制台:

如果这时我们把xml文件中的default-autowire去掉,重新启动程序并查看控制台:

纸上得来终觉浅,绝知此事要躬行!希望大家也可以自己写写代码再验证一下!

总结

到此这篇关于你所不知道的Spring自动注入详解的文章就介绍到这了,更多相关Spring自动注入内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2020-10-16

你所不知道的Spring的@Autowired实现细节分析

前言 相信很多Java开发都遇到过一个面试题:Resource和Autowired的区别是什么?这个问题的答案相信基本都清楚,但是这两者在Spring中是如何实现的呢?这就要分析Spring源码才能知道了.友情提示:本篇主要是讲解Autowired的实现原理,不会分析Spring初始化的过程,不熟悉的读者可以先阅读笔者之前的一篇文章<这一次搞懂Spring的Bean实例化原理>. 正文 在Spring Bean的整个创建过程中会调用很多BeanPostProcessor接口的的实现类: 上图是

Spring AOP拦截-三种方式实现自动代理详解

这里的自动代理,我讲的是自动代理bean对象,其实就是在xml中让我们不用配置代理工厂,也就是不用配置class为org.springframework.aop.framework.ProxyFactoryBean的bean. 总结了一下自己目前所学的知识. 发现有三种方式实现自动代理 用Spring一个自动代理类DefaultAdvisorAutoProxyCreator: <bean class="org.springframework.aop.framework.autoproxy.

Spring组件自动扫描详解及实例代码

Spring组件自动扫描详解及实例代码 问题描述 一个系统往往有成千上万的组件,如果需要手动将所有组件都纳入spring容器中管理,是一个浩大的工程. 解决方案 Spring 提供组件扫描(component scanning)功能.它能从classpath里自动扫描.侦测和实例化具有特定注解的组件.基本的注解是@Component,它标识一个受Spring管理的组件.其他特定的注解有@Repository.@Service和@Controller,它们分别标识了持久层.服务处和表现层的组件.

JSP 中spring事务配置详解

JSP 中spring事务配置详解 前几天被问到,如何防止服务器宕机,造成的数据操作的不完全. 问了一下同事,是事务.哎,恍然大悟,迷糊一时了. 声明式的事务配置,这个是最推荐的,配置到service层. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context=&

Spring集成Redis详解代码示例

本文章从头开始介绍Spring集成Redis的示例. Eclipse工程结构 如下图为我的示例工程的结构图,采用Maven构建.其中需要集成Spring,因此需要beans.xml文件配置spring的依赖注入,redis.properties配置连接服务器的配置信息. 其中工程中beans.xml和redis.properties文件直接放在了根目录,有需要的读者可以放到resource目录中. POM依赖 如下为示例POM依赖,Spring集成redis需要依赖的包为:jedis包,spri

Spring IOC原理详解

最近,买了本Spring入门书:springInAction.大致浏览了下感觉还不错.就是入门了点.Manning的书还是不错的,我虽然不像哪些只看Manning书的人那样专注于Manning,但怀着崇敬的心情和激情通览了一遍.又一次接受了IOC.DI.AOP等Spring核心概念.先就IOC和DI谈一点我的看法. IOC(DI):其实这个Spring架构核心的概念没有这么复杂,更不像有些书上描述的那样晦涩.java程序员都知道:java程序中的每个业务逻辑至少需要两个或以上的对象来协作完成,通

WebStorm ES6 语法支持设置&babel使用及自动编译(详解)

一.语法支持设置 Preferences > Languages & Frameworks > JavaScript 二.Babel安装 1.全局安装 npm install -g babel-cli 2.当前项目,适用于使用不同babel版本的情况 npm install --save-dev babel-cli 三.Babel基本用法 # 转码结果输出到标准输出 babel example.js # 转码结果写入一个文件 # --out-file 或 -o 参数指定输出文件 bab

java编程中自动拆箱与自动装箱详解

什么是自动装箱拆箱 基本数据类型的自动装箱(autoboxing).拆箱(unboxing)是自J2SE 5.0开始提供的功能. 一般我们要创建一个类的对象实例的时候,我们会这样: Class a = new Class(parameter); 当我们创建一个Integer对象时,却可以这样: Integer i = 100; (注意:不是 int i = 100; ) 实际上,执行上面那句代码的时候,系统为我们执行了:Integer i = Integer.valueOf(100); (感谢@

spring缓存代码详解

本文研究的主要是spring缓存的相关内容,具体介绍如下. 这篇文章是根据谷歌翻译大致修改出来的,由于原文不知道是什么语,所以可能导致翻译的有错误和不准确的地方,但是大致的方向感觉还是蛮不错的,所以在这里整理了一下,希望能够有所帮助. 高速缓存一直是一个非常需要这两个提高应用程序性能并降低其工作量.此外,它的用处今天是特别明显,可以作出处理成千上万的游客concurrents.D'un架构上的Web应用,高速缓存管理正交于应用程序的业务逻辑和出于这个原因,应该对应用程序本身的发展产生的影响最小.