您的位置:首页 > 编程语言 > Java开发

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接口相关的内容以及该接口的原理及工作机制,本人目前处于初级阶段,尚无法解析,在后期进行源码学习时将会重点探索,望感兴趣的猿们可以自行探索。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐