实现方法、构造器位置的自动装配

1.@Autowired注解概述

@Autowired注解的源码

package org.springframework.beans.factory.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {

    boolean required() default true;
}

@Autowired注解的源码可以看出,在@Autowired注解上标注有如下的注解信息:

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})

可以看出@Autowired注解不仅可以标注在字段上,而且还可以标注在构造方法、实例方法以及参数上

2.实战案例

2.1.案例准备

在项目中新建一个Boss类,在Boss类中有一个Car类的引用,使用@Component注解将Dog类加载到IOC容器中,如下所示:

package com.tianxia.springannotation.entity;

import lombok.Data;
import org.springframework.stereotype.Component;

import java.io.Serializable;

/**
 * Boss类
 * @author liqb
 * @date 2023-05-08 11:33
 **/
@Data
@Component
public class Boss implements Serializable {
    
    private Car car;
    
    @Override
      public String toString() {
          return "Boss [car=" + car + "]";
    }
}
package com.tianxia.springannotation.entity;

import lombok.Data;
import org.springframework.stereotype.Component;

import java.io.Serializable;

/**
 * Car类
 * @author liqb
 * @date 2023-04-27 11:43
 **/
@Data
@Component
public class Car implements Serializable {

    public Car() {
        System.out.println("car constructor...");
    }

    public void init() {
        System.out.println("car ... init...");
    }

    public void destroy() {
        System.out.println("car ... destroy...");
    }
}

新建好以上Boss类之后,在MainConfigOfAutowired配置类的@ComponentScan注解中进行配置,使其能够扫描com.tianxia.springannotation.entity包下的类,如下所示

package com.tianxia.springannotation.config;

import com.tianxia.springannotation.dao.BookDao;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

/**
 * 配置类
 * @author liqb
 * @date 2023-05-06 13:11
 **/
@Configuration
@ComponentScan({
        "com.tianxia.springannotation.service", 
        "com.tianxia.springannotation.dao", 
        "com.tianxia.springannotation.controller",
        "com.tianxia.springannotation.entity"
})
public class MainConfigOfAutowired {

    /**
     * 注入bookDao对象
     * @author liqb
     * @date 2023-05-06 13:27
     * @return
     */
    @Primary
    @Bean("bookDao2")
    public BookDao bookDao() {
        BookDao bookDao = new BookDao();
        bookDao.setLable("2");
        return bookDao;
    }
}

2.2.标注在实例方法上

可以将@Autowired注解标注在setter方法上,如下所示:

package com.tianxia.springannotation.entity;

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

import java.io.Serializable;

/**
 * Boss类
 * @author liqb
 * @date 2023-05-08 11:33
 **/
@Data
@Component
public class Boss implements Serializable {

    private Car car;

    @Autowired
    public void setCar(Car car) {
        this.car = car;
    }
    
    @Override
      public String toString() {
          return "Boss [car=" + car + "]";
      }
}

当@Autowired注解标注在方法上时,Spring容器在创建当前对象的时候,就会调用相应的方法为对象赋值。如果标注的方法存在参数时,那么方法使用的参数和自定义类型的值,需要从IOC容器中获取。

运行测试方法,输出的结果信息如下所示::

/**
 * 测试方法
 * @author liqb
 * @date 2023-05-08 11:51
 */
@Test
public void test02() {
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);

    Boss boss = applicationContext.getBean(Boss.class);
    System.out.println(boss);
    
    Car car = applicationContext.getBean(Car.class);
    System.out.println(car);

    applicationContext.close();
}

在这里插入图片描述

说明已经获取到了car的信息,也就是说可以将@Autowired注解标注在方法上

2.3.标注在构造方法上

为Boss类添加一个有参构造方法,然后去除setCar()方法上的@Autowired注解,将@Autowired注解标注在有参构造方法上,并在构造方法中打印一条信息,如下所示:

package com.tianxia.springannotation.entity;

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

import java.io.Serializable;

/**
 * Boss类
 * @author liqb
 * @date 2023-05-08 11:33
 **/
@Data
@Component
public class Boss implements Serializable {

    private Car car;

    @Autowired
    public Boss(Car car) {
        this.car = car;
        System.out.println("Boss...有参构造器");
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "Boss [car=" + car + "]";
    }
}

运行上述测试方法,输出的结果信息如下所示::

在这里插入图片描述

使用@Autowired注解标注在构造方法上时,构造方法中的参数对象也是从IOC容器中获取的

使用@Autowired注解标注在构造方法上时,如果组件中只有一个有参构造方法,那么这个有参构造方法上的@Autowired注解可以省略,并且参数位置的组件还是可以自动从IOC容器中获取

2.4.标注在参数上

可以将@Autowired注解标注在参数上,例如,在Boss类中我们将构造方法上的@Autowired注解标注在构造方法的参数上,如下所示:

package com.tianxia.springannotation.entity;

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

import java.io.Serializable;

/**
 * Boss类
 * @author liqb
 * @date 2023-05-08 11:33
 **/
@Data
@Component
public class Boss implements Serializable {

    private Car car;

    public Boss(@Autowired Car car) {
        this.car = car;
        System.out.println("Boss...有参构造器");
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "Boss [car=" + car + "]";
    }
}

可以将@Autowired注解标注在setter方法的参数上,如下所示:

package com.tianxia.springannotation.entity;

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

import java.io.Serializable;

/**
 * Boss类
 * @author liqb
 * @date 2023-05-08 11:33
 **/
@Data
@Component
public class Boss implements Serializable {

    private Car car;

    public Car getCar() {
        return car;
    }

    public void setCar(@Autowired Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "Boss [car=" + car + "]";
    }
}

最终的效果与标注在字段、实例方法和构造方法上的效果都是一样的

得出结论:无论@Autowired注解是标注在字段上、实例方法上、构造方法上还是参数上,参数位置的组件都是从IOC容器中获取

2.5.标注在方法位置

@Autowired注解可以标注在某个方法的位置上。新建一个Color类,在Color类中有一个Car类型的成员变量,如下所示:

package com.tianxia.springannotation.entity;

import lombok.Data;
import org.springframework.stereotype.Component;

import java.io.Serializable;

/**
 * 颜色类
 * @author liqb
 * @date 2023-04-23 15:35
 **/
@Data
@Component
public class Color implements Serializable {

    public Car car;

    @Override
    public String toString() {
        return "Color [car=" + car + "]";
    }
}

在MainConfigOfAutowired配置类中实例化Color类,如下所示:

@Bean
public Color color(@Autowired Car car) {
    Color color = new Color();
    color.setCar(car);
    return color;
}

@Bean
public Color color02(Car car) {
    Color color = new Color();
    color.setCar(car);
    return color;
}

运行测试方法,输出的结果信息如下所示:

/**
 * 测试方法
 * @author liqb
 * @date 2023-05-08 11:51
 */
@Test
public void test03() {
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);

    Color color = applicationContext.getBean(Color.class);
    System.out.println(color);

    applicationContext.close();
}

在这里插入图片描述

说明Car对象被成功创建并设置到Color对象中了


至此,我们可以得出结论:如果方法只有一个IOC容器中的对象作为参数,当@Autowired注解标注在这个方法的参数上时,可以将@Autowired注解省略掉。也就说@Bean注解标注的方法在创建对象的时候,方法参数的值是从IOC容器中获取的,此外,标注在这个方法的参数上的@Autowired注解可以省略。

用到最多的还是把@Autowired注解标注在方法位置,即使用@Bean注解+方法参数这种形式,此时,该方法参数的值从IOC容器中获取,并且还可以默认不写@Autowired注解,因为效果都是一样的,都能实现自动装配!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值