Spring自动装配相关注解3

Spring自动装配时可以通过@Autowired注解来完成,在自动装配的时候,@Autowired可以放在Bean中的多个位置,之前文章中介绍的是常用的方式,即:放在Bean组件中的属性位置,下面将介绍@Autowired注解放在构造器,方法,方法参数位置的用法。

温馨提示:本博客已经发布小程序,可在微信小程序中搜索”百变码农”,手机上也能看!

1、@Autowired放在属性上

示例:

a.User类:

/**
 * Created by wangbin33 on 2020/3/8.
 */
@Component
public class User {
   @Autowired
   private Pen pen;
   @Override
   public String toString() {
      return "User{" +
            "pen=" + pen +
            '}';
   }
}

b.Pen类:

/**
 * Created by wangbin33 on 2020/3/8.
 */
@Component
public class Pen {
}

c.AutowiredConfig配置类:

/**
 * Created by wangbin33 on 2020/3/8.
 */
@Configuration
@ComponentScan({"com.wb.spring.autowired"})
public class AutowiredConfig {
}

d.测试类:

/**
 * Created by wangbin33 on 2020/3/8.
 */
public class TestMain1 {
   public static void main(String[] args) {
      ApplicationContext acx = 
     new AnnotationConfigApplicationContext(AutowiredConfig.class);
      // 从容器中获取类型为Pen的Bean
      Pen pen = acx.getBean(Pen.class);
      System.out.println(pen);
      // 从容器中获取类型为User的Bean,User中注入了Pen
      User user = acx.getBean(User.class);
      System.out.println(user);
   }
}
// 输出结果:
com.wb.spring.autowired.beans.Pen@90f6bfd
User{pen=com.wb.spring.autowired.beans.Pen@90f6bfd}

可以看出,按照属性注入的Pen类型的Bean和从容器中获取到的Pen类型的Bean是同一个Bean。

2、@Autowired放在Setter方法上

示例:

只修改User类,其他类不变,如下:

/**
 * Created by wangbin33 on 2020/3/8.
 */
@Component
public class User {
   private Pen pen;

   public Pen getPen() {
      return pen;
   }
   // @Autowired标注在setter方法上,Spring在注入Pen对应的bean时,会使用
   //  setter方法进行注入
   @Autowired
   public void setPen(Pen pen) {
      this.pen = pen;
   }
   /**
     如果使用@Autowired加构造方法注入的方式,此处的@Autowired还可以放在
     构造方法的参数位置。
     public void setPen(@Autowired Pen pen) {
         this.pen = pen;
     }
   */

   @Override
   public String toString() {
      return "User{" +
            "pen=" + pen +
            '}';
   }
}

输出结果:

com.wb.spring.autowired.beans.Pen@26ba2a48
User{pen=com.wb.spring.autowired.beans.Pen@26ba2a48}

结果同上,注入的也是从容器中获取到的Bean。

3、@Autowired放在构造方法上

示例:

只修改User类,其他类不变,如下:

/**
 * Created by wangbin33 on 2020/3/8.
 */
@Component
public class User {
   private Pen pen;

   // 将@Autowired注解应用于构造方法上,Spring在注入Pen时,会自动调用该
   //  有参构造方法
   @Autowired
   public User(Pen pen) {
      this.pen = pen;
   }
   /**
   // 作用域带参构造方法上时,还可以放在构造方法的参数内部
   public User(@Autowired Pen pen) {
      this.pen = pen;
   }
   
   // 当只有一个带参构造方法需要注入的时候,还可以省略@Autowired注解,
   //  Spring在进行自动装配的时候,会直接使用该有参构造函数。
   public User(Pen pen) {
      this.pen = pen;
   }
   
   // 假如构造函数中有多个参数,也可以支持,可以忽略@Autowired注解,例如同时
   //  注入Pen对应的Bean和Book对应的Bean
   public User(Pen pen, Book book) {
      this.pen = pen;
      this.book = book;
   }
   */

   @Override
   public String toString() {
      return "User{" +
            "pen=" + pen +
            '}';
   }
}

4、@Autowired放在@Bean的方法或者参数上

示例:

a.配置类如下:

/**
 * Created by wangbin33 on 2020/3/8.
 */
@Configuration
@ComponentScan({"com.wb.spring.autowired"})
public class AutowiredConfig {
   // 通过在@Bean标注的方法上使用@Autowired,
   //  此时方法中的Pen对应的组件会被自动注入
   @Bean
   @Autuwired
   public User user(Pen pen) {
      return new User(pen);
   }
   /**
    // 此时的@Autowired注解还可以放在参数的位置或者直接省略,如下:
    @Bean
    public User user(@Autuwired Pen pen) {
    return new User(pen);
    }
    // 或者:
    @Bean
    public User user(Pen pen) {
    return new User(pen);
    }
    */

}

b.测试类:

测试类同上,代码略。

输出结果:

com.wb.spring.autowired.beans.Pen@3a03464
User{pen=com.wb.spring.autowired.beans.Pen@3a03464}

通过测试类,可以看出,从容器中获取到的Pen组件和给User中注入的Pen组件是同一个Bean组件,说明了同一个Bean组件已经被装配进入User中。

5、总结

(1)@Autowired注解可以同时标注在属性,方法,参数,构造器的位置上,通过源码也可以很容易看出来,如下:

@Target({ElementType.CONSTRUCTOR, // 构造器
   ElementType.METHOD,  // 方法
   ElementType.PARAMETER,  // 参数
   ElementType.FIELD,   // 属性
   ElementType.ANNOTATION_TYPE}) // 注解
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
   /** 
    * 表示待装配的Bean是否必须,默认为true,
    * 如果要装配的Bean不存在,会抛出异常
    */
   boolean required() default true;

}

(2)标注在方法上,如果标注在setter方法上,可以放于setter方法的参数和方法声明上。如果标注在@Bean对应的方法上,也可以放在参数位置,此时的@Autowired注解可以省略;

(3)如果标记在构造方法上,此时也可以同时标注于构造方法声明上或者构造方法的参数位置,@Autowired注解也可以省略,但是省略的前提是只有一个带参构造方法,如果有多个带参构造方法,不标注@Autowired将会抛出如下类似的异常。

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.wb.spring.autowired.beans.User]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.wb.spring.autowired.beans.User.<init>()

(4)标注在参数位置,可以放在构造方法的参数位置或者setter方法的参数位置,或者@Bean标注的方法的参数位置;

至此,Spring的@Autowired结合setter方法,构造方法,@Bean标注的方法常见用法介绍完毕,欢迎转发!

温馨提示:如果小程序端代码显示混乱,是因为移动端兼容性导致,可移步至PC端站点查看!

文章属于原创,如果转发请标注文章来源:个人小站【www.jinnianshizhunian.vip

另外提供一些优秀的Java架构师及IT开发视频,书籍资料。无需注册,无需登录即可下载,免费下载地址:https://www.592xuexi.com