SpringBean的一些总结

一、Spring配置类的实现

1、基本介绍

Spring Boot 推荐使用 java 配置完全代替 XML 配置,java 配置是通过 @Configration@Bean注解实现的,二者作用如下:

  • @Configration 注解:声明当前类是一个配置类,相当于 Spring 中的一个 XML 文件

  • @Bean 注解:作用在方法上,声明当前方法的返回值是一个 Bean

下面是最简单的一个示例

@Configuration
public class UserConfig {

    @Bean
    public String hello(){
        return "hello world";
    }
}

/**==============调用==============*/
@RestController
public class UserController {

    @Autowired
    String hello;

    @GetMapping("/hello")
    public String hello(){
        return hello;
    }

}

2、@Bean 注解详解

2.1 使用说明

  • @Bean 注解作用在方法上

  • @Bean 指示一个方法返回一个 Spring 容器管理的 Bean

  • @Bean 方法名与返回类名一致,首字母小写

  • @Bean 一般和 @Component 或者 @Configuration 一起使用

  • @Bean 注解默认作用域为单例 singleton 作用域,可通过 @Scope("prototype") 设置为原型作用域

2.2 Bean名称

1、默认情况下 Bean 名称就是方法名,比如下面 Bean 名称便是 myBean

@Bean
public MyBean myBean() {
    return new MyBean();
}

2、 @Bean 注解支持设置别名。比如下面除了主名称 myBean 外,还有个别名 myBean1(两个都可以使用)

@Bean("myBean1")
public MyBean myBean() {
    return new MyBean();
}

3、@Bean 注解可以接受一个 String 数组设置多个别名。比如下面除了主名称 myBean 外,还有别名 myBean1、myBean2(三个都可以使用)

@Bean({"myBean1", "myBean2"})
public MyBean myBean() {
    return new MyBean();
}

2.3 @Bean 与其他注解一起使用

@Bean 注解常常与 @Scope、@Lazy,@DependsOn 和 @link Primary 注解一起使用:

  • @Profile 注解:为在不同环境下使用不同的配置提供了支持,如开发环境和生产环境的数据库配置是不同的

  • @Scope 注解:将 Bean 的作用域从单例改变为指定的作用域

  • @Lazy注解:只有在默认单例作用域的情况下才有实际效果

  • @DependsOn 注解:表示在当前 Bean 创建之前需要先创建特定的其他 Bean

// @Bean(initMethod="init", destroyMethod="destroy") 可以调用初始化和销毁的方法
@Bean
//  @Scope 注解将其改成 prototype 原型模式(每次获取 Bean 的时候会有一个新的实例)
@Scope("prototype")
public MyBean myBean() {
    return new MyBean();
}

3、@Configration 注解详解

3.1 使用说明

  • @Configration 注解作用在类、接口(包含注解)上

  • @Configuration 用于定义配置类,可替换 xml 配置文件

  • @Configration 注解类中可以声明一个或多个 @Bean 方法

  • @Configration 注解作用的类不能是 final 类型

  • 嵌套的 @Configration 类必须是 static 的

@SpringBootApplication
public class SpringBeanApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context
                = SpringApplication.run(SpringBeanApplication.class, args);
        String myBean = (String) context.getBean("hello");
        System.out.println(myBean);
    }
}

3.2 @Bean与@Condition的组合

在这里插入图片描述

二、Bean注入的一些总结

1、多Bean注入

1.1 简介

@Resource默认是按照名字注入,@Autowired默认是按照类型注入,当一个容器内只有一个名字或者类型时,直接走默认就可以,Spring会自动帮我们注入;同时当只;有一个bean时,变量名取任何合法名字都可以。

但是当有多个相同类型的bean时,变量名必须根据注入Bean类名字获取,或者使用@Qualifier注解指定某个Bean

1.2 代码详解

创建User类

public class User {

    private String age;

    private String name;

    public User(String age, String name) {
        this.age = age;
        this.name = name;
    }


    @Override
    public String toString() {
        return "User{" +
                "age='" + age + '\'' +
                ", name='" + name + '\'' +
                '}';
    }

}

创建config类,bean注入

@Configuration
public class UserConfig {

    @Bean
    public User user(){
        User user = new User("18", "shawn");
        return user;
    }

    @Bean
    public User user1(){
        User user = new User("19", "shawn1");
        return user;
    }

    @Bean
    public User user2(){
        User user = new User("20", "shawn2");
        return user;
    }
}

使用

@RestController
public class UserController {

    // 默认按照类型或者注入,下面两种都可以,当只有一个bean时,变量名取任何合法名字都可以
    //@Resource
    @Autowired
    User user;

    // Resource指定
    @Resource(name = "user1")
    User user11;

    // 指定
    @Autowired
    @Qualifier(value = "user2")
    User user22;

    @GetMapping("/hello")
    public void hello(){
        System.out.println(user11);
    }

}

2、Spring容器有参与无参构造

  • 一般一个类他会自带一个默认的无参构造方法,如果你在其中写入了有参构造,在没有重新写入无参构造的情况下,该无参构造方法就不存在了

  • 在使用spring框架时,在使用一个类的时候,spring容器会自动对该类进行实例化,但是该类必须时无参构造的,相当于spring的默认设置

  • 如果在使用spring框架时,实体类的初始化方法是有参构造,那么需要在配置文件中进行配置(即.xml文件)或者注入相应的bean之后spring容器才能对该类进行实例化,否则会报错

  • 当一个类存在有参和无参构造函数时,默认为无参,如果要执行有参构造,可以在构造函数上加@Autowired注解

@Configuration
public class UserConfig {

    @Bean
    public User user(){
        User user = new User("18", "shawn");
        return user;
    }
}

/**=====================分割线==============*/


@Service
public class UserService {

    private User user;

    // 默认无参
    public UserService(){
        System.out.println("UserService空构造函数");
    }
    //@Autowired 会执行有参,多个bean的话注意对应方法名 
    @Autowired
    public UserService(User user){
        this.user=user;
        System.out.println("UserService非空构造函数"+ user);
    }


    public void getUser(){
        System.out.println("获取到的User为"+user);
    }
}

3、@Bean 与 @Component

3.1 简介

当@Bean 与 @Component 同时作用同一个类时,Spring容器种到底有几个 对象

@Configuration
public class UserConfig {

    @Bean
    public UserService userService(){
        return new UserService();
    }
}

/**==========================================*/

@Service
public class UserService {

    private User user;

    // 默认无参
    public UserService(){
        System.out.println("UserService空构造函数");
    }

    @Autowired
    public UserService(User user){
        this.user=user;
        System.out.println("UserService非空构造函数"+ user);
    }

    public void getUser(){
        System.out.println("获取到的User为"+user);
    }
}

3.2 解释说明

具体的源码参考:https://cloud.tencent.com/developer/article/1886414

@Configuration 包含了 @Component ,在Spring扫描过程中,@Configuration+@Bean方式会覆盖先创建的@Service的Bean

但在 Spring 5.1.2.RELEASE (Spring Boot 则是 2.1.0.RELEASE )后,新增了配置项allowBeanDefinitionOverriding 来控制是否允许 BeanDefinition 覆盖,默认情况下是不允许的。我们可以在配置文件中配置:spring.main.allow-bean-definition-overriding=true ,允许 BeanDefinition 覆盖

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值