Spring 基于注解的配置(二)(@Required,@Autowired, @Qualifier)
2017-10-06 23:48
567 查看
@Required
应用范围:bean属性的setter方法
作用:检查注解的Bean属性是否在XML中进行配置,若未进行配置则容器会抛出一个BeanInitializationException异常
使用方法:
方法一:
包函 <context:annotation-config />
<context:annotation-config />
<bean id="Hello"
class="com.spring.demo.Hello">
<
4000
span style="color:rgb(255,255,255);"> <!-- <property name="name" value="ruanjianlin"/> -->
<property
name="id"
value="12"
/>
</bean>
Hello.java
package
com.spring.demo;
import org.springframework.beans.factory.annotation.Required;
/**
* Created by ruanjianlin on 2017/9/27.
*/
public class Hello {
private
String name;
private int id;
public Hello() {
}
public
Hello(String name, int
id) {
this.name
= name;
this.id
= id;
}
public
String getName() {
return
name;
}
@Required
public void
setName(String name) {
this.name
= name;
}
public int
getId() {
return
id;
}
public void
setId(int
id) {
this.id
= id;
}
public void
say(){
System.out.println("hello");
}
@Override
public
String toString() {
return
"Hello{" +
"name='"
+ name
+ '\''
+
", id="
+ id
+
'}';
}
}
运行的结果:
Property 'name' is required for bean 'Hello'
方法二:
bean 配置文件包函“RequiredAnnotationBeanPostProcessor”
<bean
class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
<bean id="Hello"
class="com.spring.demo.Hello">
<!-- <property name="name" value="ruanjianlin"/> -->
<property
name="id"
value="12"
/>
</bean>
与@Autowired的联系:
1.@Autowired 的必要属性,建议使用@Required注解
2.每个类只能有一个构造器被标记为required=true(每个类有很多的构造器,默认的required=false)
3.如果因为找不到合适的bean或者含有多个Bean将会导致autowiring失败抛出异常,使用@Autowired(required=false)解决(主要用于构造方法和Bean
setter方法上,也可以用于属性上)
Autowired是一种函数,可以对成员变量、方法和构造函数进行标注,来完成自动装配的工作,@Autowired标注可以放在成员变量上,也可以放在成员变量的set方法上。
这里必须明确:@Autowired是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Qualifier使用
Spring 2.5 引入了 @Autowired注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 通过
@Autowired的使用来消除set
,get方法。
Spring遇到一个在 setter方法中使用的
@Autowired注释,setter方法会在方法中视图执行 byType 自动连接
Setter方法中的@Autowired:
Computer.java
package
com.spring.Autowire;
/**
* Created by ruanjianlin on 2017/10/6.
*/
public class Computer {
publicComputer() {
System.out.println("You get a new computer");
}
public voidplay(){
System.out.println("The computer is working! ");
}
}
Human.java
package
com.spring.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Created by ruanjianlin on 2017/10/6.
*/
public class Human {
privateComputer
computer;
public Human() {
System.out.println("The function of Human constructor is working!");
}
publicHuman(Computer computer) {
this.computer= computer;
System.out.println("The
function of Human which has a parameter is working!");
}
publicComputer
getComputer() {
returncomputer;
}
@Autowired
public voidsetComputer(Computer computer) {
this.computer= computer;
System.out.println("The
function of setComputer is working!");
}
public voidplay(){
computer.play();
}
}
Autowired_Demo.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<bean id="human"class="com.spring.Autowire.Human">
</bean>
<bean id="computer"class="com.spring.Autowire.Computer">
</bean>
</beans>
输出结果:
The function of Human constructor is working!
You get a new computer
The function of setComputer is working!
The computer is working!
调用的方法:
Human()
Computer()
setComputer(Computer computer)
play()
构造函数中的@Autowired:
package
com.spring.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Created by ruanjianlin on 2017/10/6.
*/
public class Human {
privateComputer
computer;
public Human() {
System.out.println("The
function of Human constructor is working!");
}
@Autowired
publicHuman(Computer computer) {
this.computer= computer;
System.out.println("The
function of Human which has a parameter is working!");
}
publicComputer
getComputer() {
returncomputer;
}
public voidsetComputer(Computer computer) {
this.computer= computer;
System.out.println("The
function of setComputer is working!");
}
public voidplay(){
computer.play();
}
}
输出结果:
You get a new computer
The function of Human which has a parameter is working!
The computer is working!
运行的方法:
Human(Computer computer)
Computer()
play()
属性中的@Autowired:
Human.java
package
com.spring.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Created by ruanjianlin on 2017/10/6.
*/
public class Human {
@Autowired
privateComputer
computer;
public Human() {
System.out.println("The function of Human constructor is working!");
}
publicHuman(Computer computer) {
this.computer= computer;
System.out.println("The
function of Human which has a parameter is working!");
}
publicComputer
getComputer() {
returncomputer;
}
public voidsetComputer(Computer computer) {
this.computer= computer;
System.out.println("The
function of setComputer is working!");
}
public voidplay(){
computer.play();
}
}
输出结果:
The function of Human constructor is working!
You get a new computer
The computer is working!
Disconnected from the target VM, address: '127.0.0.1:54693', transport: 'socket'
运行的方法:
Human()
Computer()
play()
属性上的添加@Autowired后getBean时并没有调用setComputer(Computer computer)
原理解释:
(1)Spring 通过一个 BeanPostProcessor 对 @Autowired进行解析,所以要让
@Autowired起作用必须事先在
Spring容器中声明
AutowiredAnnotationBeanPostProcessor Bean。
@Autowired在成员上的配置:Spring将直接采用 Java反射机制对Human中的computer 这个私有成员变量进行自动注入。所以对成员变量使用
@Autowired后,可将它的 setter方法(setComputer(Computer computer)
)从
Human中删除。
(2) @Autowired对方法或构造函数进行标注:(按照本示例作解析)如果构造函数有一个形参,是computer,@Autowired寻找和它类型匹配的
Bean(byType),将它作为Human (Computer
computer)的参数来创建 Human Bean 此时不再调用setter方法,而@Autowired在setter上时会通过上述方式进行Bean的注册,而不会调用带参数的构造函数
(3)在使用Spring框架中@Autowired标签时默认情况下使用@Autowired
注释进行自动注入时,Spring容器中匹配的候选
Bean数目必须有且仅有一个。当找不到一个匹配的
Bean时,Spring
容器将抛BeanCreationException异常,并指出必须至少拥有一个匹配的 Bean。(因此可以使用 @Qualifier解除歧义)
@Qualifier的使用
@Autowired 可以对成员变量、方法以及构造函数进行注释,而
@Qualifier 的标注对象是成员变量、方法入参、构造函数入参。
代码示例:
Sing接口类:
package
com.spring.Autowire;
import org.springframework.stereotype.Component;
/**
* Created by ruanjianlin on 2017/10/7.
*/
@Component("sing")
public interface Sing {
public voidsing();
}
ManSing.java
package
com.spring.Autowire;
import org.springframework.stereotype.Component;
/**
* Created by ruanjianlin on 2017/10/7.
*/
@Component("manSing")
public class ManSingimplements
Sing {
public voidsing() {
System.out.println("This is a man!");
}
}
WomanSing.java
package
com.spring.Autowire;
import org.springframework.stereotype.Component;
/**
* Created by ruanjianlin on 2017/10/7.
*/
@Component("womanSing")
public class WomanSingimplements
Sing {
public voidsing() {
System.out.println("This is a woman!");
}
}
Human.java
package
com.spring.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
/**
* Created by ruanjianlin on 2017/10/6.
*/
public class Human {
privateComputer
computer;
@Autowired
@Qualifier("manSing")
privateSing
sing;
public Human() {
System.out.println("The function of Human constructor is working!");
}
@Autowired
publicHuman(Computer computer) {
this.computer= computer;
System.out.println("The
function of Human which has a parameter is working!");
}
publicComputer
getComputer() {
returncomputer;
}
public voidsetComputer(Computer computer) {
this.computer= computer;
System.out.println("The
function of setComputer is working!");
}
public voidsetSing(Sing sing) {
this.sing= sing;
}
public voidplay(){
computer.play();
sing.sing();
}
}
Autowired_Demo.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<bean id="human"class="com.spring.Autowire.Human">
</bean>
<bean id="computer"class="com.spring.Autowire.Computer">
</bean>
<context:component-scanbase-package="com.spring"use-default-filters="false">
<context:include-filtertype="regex"expression="com.spring.Autowire.*"/>
</context:component-scan>
</beans>
上述为正确代码运行结果如下:
You get a new computer
The function of Human which has a parameter is working!
The computer is working!
This is a man !
当我们不使用@Qualifier时报错情况主要如下所示:
org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.spring.Autowire.Sing com.spring.Autowire.Human.sing; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type [com.spring.Autowire.Sing] is defined: expected single matching bean but found 2: manSing,womanSing
错误解析:由报错信息可知产生了歧义,系统无法决定 manSing,womanSing
关于BeanPostProcessor接口相关的内容以及该接口的原理及工作机制,本人目前处于初级阶段,尚无法解析,在后期进行源码学习时将会重点探索,望感兴趣的猿们可以自行探索。
应用范围:bean属性的setter方法
作用:检查注解的Bean属性是否在XML中进行配置,若未进行配置则容器会抛出一个BeanInitializationException异常
使用方法:
方法一:
包函 <context:annotation-config />
<context:annotation-config />
<bean id="Hello"
class="com.spring.demo.Hello">
<
4000
span style="color:rgb(255,255,255);"> <!-- <property name="name" value="ruanjianlin"/> -->
<property
name="id"
value="12"
/>
</bean>
Hello.java
package
com.spring.demo;
import org.springframework.beans.factory.annotation.Required;
/**
* Created by ruanjianlin on 2017/9/27.
*/
public class Hello {
private
String name;
private int id;
public Hello() {
}
public
Hello(String name, int
id) {
this.name
= name;
this.id
= id;
}
public
String getName() {
return
name;
}
@Required
public void
setName(String name) {
this.name
= name;
}
public int
getId() {
return
id;
}
public void
setId(int
id) {
this.id
= id;
}
public void
say(){
System.out.println("hello");
}
@Override
public
String toString() {
return
"Hello{" +
"name='"
+ name
+ '\''
+
", id="
+ id
+
'}';
}
}
运行的结果:
Property 'name' is required for bean 'Hello'
方法二:
bean 配置文件包函“RequiredAnnotationBeanPostProcessor”
<bean
class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
<bean id="Hello"
class="com.spring.demo.Hello">
<!-- <property name="name" value="ruanjianlin"/> -->
<property
name="id"
value="12"
/>
</bean>
与@Autowired的联系:
1.@Autowired 的必要属性,建议使用@Required注解
2.每个类只能有一个构造器被标记为required=true(每个类有很多的构造器,默认的required=false)
3.如果因为找不到合适的bean或者含有多个Bean将会导致autowiring失败抛出异常,使用@Autowired(required=false)解决(主要用于构造方法和Bean
setter方法上,也可以用于属性上)
Autowired是一种函数,可以对成员变量、方法和构造函数进行标注,来完成自动装配的工作,@Autowired标注可以放在成员变量上,也可以放在成员变量的set方法上。
这里必须明确:@Autowired是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Qualifier使用
Spring 2.5 引入了 @Autowired注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 通过
@Autowired的使用来消除set
,get方法。
Spring遇到一个在 setter方法中使用的
@Autowired注释,setter方法会在方法中视图执行 byType 自动连接
Setter方法中的@Autowired:
Computer.java
package
com.spring.Autowire;
/**
* Created by ruanjianlin on 2017/10/6.
*/
public class Computer {
publicComputer() {
System.out.println("You get a new computer");
}
public voidplay(){
System.out.println("The computer is working! ");
}
}
Human.java
package
com.spring.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Created by ruanjianlin on 2017/10/6.
*/
public class Human {
privateComputer
computer;
public Human() {
System.out.println("The function of Human constructor is working!");
}
publicHuman(Computer computer) {
this.computer= computer;
System.out.println("The
function of Human which has a parameter is working!");
}
publicComputer
getComputer() {
returncomputer;
}
@Autowired
public voidsetComputer(Computer computer) {
this.computer= computer;
System.out.println("The
function of setComputer is working!");
}
public voidplay(){
computer.play();
}
}
Autowired_Demo.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<bean id="human"class="com.spring.Autowire.Human">
</bean>
<bean id="computer"class="com.spring.Autowire.Computer">
</bean>
</beans>
输出结果:
The function of Human constructor is working!
You get a new computer
The function of setComputer is working!
The computer is working!
调用的方法:
Human()
Computer()
setComputer(Computer computer)
play()
构造函数中的@Autowired:
package
com.spring.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Created by ruanjianlin on 2017/10/6.
*/
public class Human {
privateComputer
computer;
public Human() {
System.out.println("The
function of Human constructor is working!");
}
@Autowired
publicHuman(Computer computer) {
this.computer= computer;
System.out.println("The
function of Human which has a parameter is working!");
}
publicComputer
getComputer() {
returncomputer;
}
public voidsetComputer(Computer computer) {
this.computer= computer;
System.out.println("The
function of setComputer is working!");
}
public voidplay(){
computer.play();
}
}
输出结果:
You get a new computer
The function of Human which has a parameter is working!
The computer is working!
运行的方法:
Human(Computer computer)
Computer()
play()
属性中的@Autowired:
Human.java
package
com.spring.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Created by ruanjianlin on 2017/10/6.
*/
public class Human {
@Autowired
privateComputer
computer;
public Human() {
System.out.println("The function of Human constructor is working!");
}
publicHuman(Computer computer) {
this.computer= computer;
System.out.println("The
function of Human which has a parameter is working!");
}
publicComputer
getComputer() {
returncomputer;
}
public voidsetComputer(Computer computer) {
this.computer= computer;
System.out.println("The
function of setComputer is working!");
}
public voidplay(){
computer.play();
}
}
输出结果:
The function of Human constructor is working!
You get a new computer
The computer is working!
Disconnected from the target VM, address: '127.0.0.1:54693', transport: 'socket'
运行的方法:
Human()
Computer()
play()
属性上的添加@Autowired后getBean时并没有调用setComputer(Computer computer)
原理解释:
(1)Spring 通过一个 BeanPostProcessor 对 @Autowired进行解析,所以要让
@Autowired起作用必须事先在
Spring容器中声明
AutowiredAnnotationBeanPostProcessor Bean。
@Autowired在成员上的配置:Spring将直接采用 Java反射机制对Human中的computer 这个私有成员变量进行自动注入。所以对成员变量使用
@Autowired后,可将它的 setter方法(setComputer(Computer computer)
)从
Human中删除。
(2) @Autowired对方法或构造函数进行标注:(按照本示例作解析)如果构造函数有一个形参,是computer,@Autowired寻找和它类型匹配的
Bean(byType),将它作为Human (Computer
computer)的参数来创建 Human Bean 此时不再调用setter方法,而@Autowired在setter上时会通过上述方式进行Bean的注册,而不会调用带参数的构造函数
(3)在使用Spring框架中@Autowired标签时默认情况下使用@Autowired
注释进行自动注入时,Spring容器中匹配的候选
Bean数目必须有且仅有一个。当找不到一个匹配的
Bean时,Spring
容器将抛BeanCreationException异常,并指出必须至少拥有一个匹配的 Bean。(因此可以使用 @Qualifier解除歧义)
@Qualifier的使用
@Autowired 可以对成员变量、方法以及构造函数进行注释,而
@Qualifier 的标注对象是成员变量、方法入参、构造函数入参。
代码示例:
Sing接口类:
package
com.spring.Autowire;
import org.springframework.stereotype.Component;
/**
* Created by ruanjianlin on 2017/10/7.
*/
@Component("sing")
public interface Sing {
public voidsing();
}
ManSing.java
package
com.spring.Autowire;
import org.springframework.stereotype.Component;
/**
* Created by ruanjianlin on 2017/10/7.
*/
@Component("manSing")
public class ManSingimplements
Sing {
public voidsing() {
System.out.println("This is a man!");
}
}
WomanSing.java
package
com.spring.Autowire;
import org.springframework.stereotype.Component;
/**
* Created by ruanjianlin on 2017/10/7.
*/
@Component("womanSing")
public class WomanSingimplements
Sing {
public voidsing() {
System.out.println("This is a woman!");
}
}
Human.java
package
com.spring.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
/**
* Created by ruanjianlin on 2017/10/6.
*/
public class Human {
privateComputer
computer;
@Autowired
@Qualifier("manSing")
privateSing
sing;
public Human() {
System.out.println("The function of Human constructor is working!");
}
@Autowired
publicHuman(Computer computer) {
this.computer= computer;
System.out.println("The
function of Human which has a parameter is working!");
}
publicComputer
getComputer() {
returncomputer;
}
public voidsetComputer(Computer computer) {
this.computer= computer;
System.out.println("The
function of setComputer is working!");
}
public voidsetSing(Sing sing) {
this.sing= sing;
}
public voidplay(){
computer.play();
sing.sing();
}
}
Autowired_Demo.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<bean id="human"class="com.spring.Autowire.Human">
</bean>
<bean id="computer"class="com.spring.Autowire.Computer">
</bean>
<context:component-scanbase-package="com.spring"use-default-filters="false">
<context:include-filtertype="regex"expression="com.spring.Autowire.*"/>
</context:component-scan>
</beans>
上述为正确代码运行结果如下:
You get a new computer
The function of Human which has a parameter is working!
The computer is working!
This is a man !
当我们不使用@Qualifier时报错情况主要如下所示:
org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.spring.Autowire.Sing com.spring.Autowire.Human.sing; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type [com.spring.Autowire.Sing] is defined: expected single matching bean but found 2: manSing,womanSing
错误解析:由报错信息可知产生了歧义,系统无法决定 manSing,womanSing
关于BeanPostProcessor接口相关的内容以及该接口的原理及工作机制,本人目前处于初级阶段,尚无法解析,在后期进行源码学习时将会重点探索,望感兴趣的猿们可以自行探索。
相关文章推荐
- spring基于注解的配置 @Required @Autowired
- Spring AOP注解通过@Autowired,@Resource,@Qualifier,@PostConstruct,@PreDestroy注入属性的配置文件详解
- Spring AOP注解通过@Autowired,@Resource,@Qualifier,@PostConstruct,@PreDestroy注入属性的配置文件详解
- Spring使用@Autowired,@Qualifier,@Resource注解配置bean
- Spring AOP注解通过@Autowired,@Resource,@Qualifier,@PostConstruct,@PreDestroy注入属性的配置文件详解
- Spring AOP注解通过@Autowired,@Resource(J2EE提供),@Qualifier,@PostConstruct,@PreDestroy注入属性的配置文件详解
- Spring AOP注解通过@Autowired,@Resource,@Qualifier,@PostConstruct,@PreDestroy注入属性的配置文件详解
- Spring AOP注解通过@Autowired,@Resource,@Qualifier,@PostConstruct,@PreDestroy注入属性的配置文件详解
- Spring AOP注解通过@Autowired,@Resource,@Qualifier,@PostConstruct,@PreDestroy注入属性的配置文件详解
- Spring AOP注解通过@Autowired,@Resource,@Qualifier,@PostConstruct,@PreDestroy注入属性的配置文件详解
- Spring AOP注解通过@Autowired,@Resource,@Qualifier,@PostConstruct,@PreDestroy注入属性的配置文件详解
- Spring_spring自动装配置注解(@Autowired)指定要装配置的参数(@Qualifier)
- Spring @Autowired,@Resource,@Required注解的用法和作用
- Spring注解@Component、@Repository、@Service、@Controller @Resource、@Autowired、@Qualifier 解析
- 04 Spring 注解配置,简化xml配置,@Service、@Autowired简介
- spring 注解Resource/Autowired以及配置文件中default-autowire参数
- Spring @Resource、@Autowired、@Qualifier的注解注入及区别
- 终极讲解,看了立马懂 --》Spring注解@Component、@Repository、@Service、@Controller @Resource、@Autowired、@Qualifier 解析
- 04 Spring 注解配置,简化xml配置,@Service、@Autowired简介
- Spring @Resource、@Autowired、@Qualifier的注解注入详解