Spring @Autowired 用法

首先看下@Component

在类级别上添加了@Component注解,Spring在启动时就会找到该类(spring采用基于注解和类路径扫描的方式时),并为其生成一个实例,然后,纳入spring容器进行管理。

举例 1 :

参见:@Component @Bean @Configuration 用法

举例 2 :

代码如下(springboot项目):

package com.xl.test.logtest.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class AutowiredTest {
	@Autowired(required=false)
	public AutowiredTest(Desk dk) {
		System.out.println("==================第一个@Autowired构造器执行================");
		System.out.println("==================dk================"+dk);
	}
	
	public AutowiredTest() {
		System.out.println("==================无参构造函数================");
	}
	
//	@Autowired(required=false)
//	public AutowiredTest(Desk dk, Bench bh) {
//		System.out.println("==================第二个@Autowired构造器执行================");
//	}
	
}

@Component
class Desk {
	
}

@Component
class Bench {
	
}

如上,类Desk上加上了注解Component, 在类AutowiredTest 中就可自动注入Desk的实例 dk:
在这里插入图片描述
启动项目,验证:
在这里插入图片描述
当然,这个实例是spring通过调用Desk的默认的无参构造器(也是当前唯一的一个构造器)生成的

验证是否调用的是默认构造器

在AutowiredTest中显示的声明无参/默认构造函数以及两个有参数的构造函数:

package com.xl.test.logtest.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class AutowiredTest {
//	@Autowired(required=false)
	public AutowiredTest(Desk dk) {
		System.out.println("==================第一个@Autowired构造器执行================");
		System.out.println("==================dk================"+dk);
	}
	
	public AutowiredTest() {
		System.out.println("==================无参构造函数================");
	}
	
//	@Autowired(required=false)
	public AutowiredTest(Desk dk, Bench bh) {
		System.out.println("==================第二个@Autowired构造器执行================");
	}
	
}

@Component
class Desk {
	
}

@Component
class Bench {
	
}

启动项目,验证:只执行了默认的构造函数,其余两个并未执行
在这里插入图片描述

如何,在启动的时候执行有参数的构造函数??,这就要看@Autowired注解了!

@Autowired注解

Marks a constructor, field, setter method, or config method as to be autowired by Spring's dependency injection facilities

将构造器、域、setter方法或者配置方法标记为被注入的对象,也就是@Autowired注解可以用于构造器、域、setter方法或者配置方法上。当然,是通过Spring的依赖注入机制来完成依赖注入的。

根据官方文档,@Autowired注解分别对构造器、域、方法、参数等等做了详细解释,这里仅讨论构造器:

Only one constructor (at max) of any given bean class may declare this annotation with the 'required' parameter set to 
true, indicating the constructor to autowire when used as a Spring bean. If multiple non-required constructors declare 
the annotation, they will be considered as candidates for autowiring. The constructor with the greatest number of 
dependencies that can be satisfied by matching beans in the Spring container will be chosen. If none of the candidates 
can be satisfied, then a primary/default constructor (if present) will be used. If a class only declares a single constructor 
to begin with, it will always be used, even if not annotated. An annotated constructor does not have to be public.

当一个类是作为Spring的bean管理时,并且@Autowired的属性required为true(默认值)时,这个类的只能有一个构造函数能使用@Autowired注解: 那么,在启动项目时,会执行该构造器同时Spring会注入该构造器的参数实例(或者称为 依赖 ),如下所示:

package com.xl.test.logtest.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class AutowiredTest {
	@Autowired
	public AutowiredTest(Desk dk) {
		System.out.println("==================第一个@Autowired构造器执行================");
		System.out.println("==================dk================"+dk);
	}
	
	public AutowiredTest() {
		System.out.println("==================无参构造函数================");
	}
	
//	@Autowired
	public AutowiredTest(Desk dk, Bench bh) {
		System.out.println("==================第二个@Autowired构造器执行================");
	}
	
}

@Component
class Desk {
	
}

@Component
class Bench {
	
}

启动项目,控制台打印如下:
在这里插入图片描述
延伸: 如果构造器中的参数实例(依赖)也就是 public AutowiredTest(Desk dk) 中的 dk为null(即是:Spring没有初始化并管理Desk的bean (dk) ),那么启动时会报错,如下:
将类Desk的注解@Component去掉:Spring就不会初始化Desk的实例了,其他的保持不变

package com.xl.test.logtest.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class AutowiredTest {
	@Autowired
	public AutowiredTest(Desk dk) {
		System.out.println("==================第一个@Autowired构造器执行================");
		System.out.println("==================dk================"+dk);
	}
	
	public AutowiredTest() {
		System.out.println("==================无参构造函数================");
	}
	
//	@Autowired
	public AutowiredTest(Desk dk, Bench bh) {
		System.out.println("==================第二个@Autowired构造器执行================");
	}
	
}

//@Component
class Desk {
	
}

@Component
class Bench {
	
}

启动报错如下:
在这里插入图片描述
解决办法:
1、如上图
2、更改@Autowired的属性required的默认值,将其设置为false
true:默认值,表示所需要的依赖必须存在
false:表示所需依赖可以不存在,但是不会执行该构造器,转而执行默认的构造器(需显示的声明默认构造器,否则,还是会报错:找不到Desk的bean),如下:

Description:

Parameter 0 of constructor in com.xl.test.logtest.annotation.AutowiredTest required a bean of type 
'com.xl.test.logtest.annotation.Desk' that could not be found.

验证如下:

package com.xl.test.logtest.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class AutowiredTest {
	@Autowired(required=false)
	public AutowiredTest(Desk dk) {
		System.out.println("==================第一个@Autowired构造器执行================");
		System.out.println("==================dk================"+dk);
	}
	
	public AutowiredTest() {
		System.out.println("==================无参构造函数================");
	}
	
//	@Autowired
	public AutowiredTest(Desk dk, Bench bh) {
		System.out.println("==================第二个@Autowired构造器执行================");
	}
	
}

//@Component
class Desk {
	
}

@Component
class Bench {
	
}

在这里插入图片描述
此时,项目正常启动,但是,并没有执行@Autowired注解的构造器。

==小结:也就是只有提供了构造器的依赖实例(参数示例),才会执行构造器,那就是说@Autowired注解的属性required=true才有意义,因为required=false,如果有依赖就执行@Autowired注解的构造器; 没有依赖就执行默认的构造器(前提是:显示声明默认构造器!),但是没有执行@Autowired注解的构造器啊 ==

required=false真的没有意义吗? 不是的!,看下官方的文档:

If multiple non-required constructors declare the annotation, they will be considered as candidates for autowiring. The constructor with the greatest number of dependencies that can be satisfied by matching beans in the Spring container will be chosen.

如果有多个构造器的required都为false,那么这些构造器都会作为候选待执行构造器,最终执行哪一个取决于哪个构造器在spring容器中的依赖(参数实例)更多,执行依赖最多的一个构造器;如果所有的构造器的依赖数量都是零,那么就执行默认的构造器!但是,需要显示的声明默认的构造器,如果没有声明则会报错!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值