SpringBoot @Configuration与@Bean注解使用介绍

 更新时间:2022年10月13日 15:44:43   作者:一根头发学一年  
这篇文章主要介绍了SpringBoot中的@Configuration与@Bean注解,在进行项目编写前,我们还需要知道一个东西,就是SpringBoot对我们的SpringMVC还做了哪些配置,包括如何扩展,如何定制,只有把这些都搞清楚了,我们在之后使用才会更加得心应手

之前我们都是通过xml的方式定义bean,里面会写很多bean元素,然后spring启动的时候,就会读取bean xml配置文件,然后解析这些配置,然后会将这些bean注册到spring容器中,供使用者使用。

Spring3.0开始,@Configuration用于定义配置类,定义的配置类可以替换xml文件,一般和@Bean注解联合使用。

@Configuration注解可以加在类上,让这个类的功能等同于一个bean xml配置文件。

@Bean注解类似于bean xml配置文件中的bean元素,用来在spring容器中注册一个bean。

demo示例

1.创建一个工程

2.创建bean文件夹并创建两个示例用户和部门

如下:

用户

package com.example.ethan.bean;
public class User {
    private String name;
    private Integer age;
    private Dept dept;
	public User() {
	}
    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
    public Dept getDept() {
        return dept;
    }
    public void setDept(Dept dept) {
        this.dept = dept;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
}

部门

package com.example.ethan.bean;
public class Dept {
    private String name;
    public Dept(String name) {
        this.name = name;
    }
}

3.创建配置类

使用@Configuration注解,并使用@Bean注解创建bean

package com.example.ethan.config;
import com.example.ethan.bean.Dept;
import com.example.ethan.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration  //告诉SpringBoot这是一个配置类 == 配置文件
public class ConfigDemo {
    @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
    public User user01(){
        User zhangsan = new User("zhangsan", 18);
        return zhangsan;
    }
    @Bean("my rd")
    public Dept rd(){
        return new Dept("研发部");
    }
}

4.在主程序查看

编写主程序,查看容器中的Bean

package com.example.ethan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class EthanApplication {
    public static void main(String[] args) {
        // 返回ioc容器
        ConfigurableApplicationContext run = SpringApplication.run(EthanApplication.class, args);
        // 查看容器组件
        String[] beanDefinitionNames = run.getBeanDefinitionNames();
        System.out.println("========================");
        for (String name : beanDefinitionNames) {
            System.out.println(name);
        }
    }
}

运行后可以看到configDemo、user01、my rd都已经被容器管理。

特点和特性

1.配置类本身也是组件,也会有被IOC容器管理的Bean,且是一个单实例的代理对象。

在主程序验证代码如下:

ConfigDemo bean = run.getBean(ConfigDemo.class);
 System.out.println(bean);

// 结果:com.example.ethan.config.ConfigDemo$$EnhancerBySpringCGLIB$$24eef7b3@a619c2

可以看到得到的bean是一个CGLIB代理对象。

2.默认被IOC容器管理@Bean注解产生的Bean是单实例的。

在主程序验证代码如下:

Dept d1 = run.getBean("my rd", Dept.class);
Dept d2 = run.getBean("my rd", Dept.class);
System.out.println("组件:"+(d1 == d2));
// 组件:true

结果为true,证明@Bean注解产生的Bean是单实例的。

3.@configration的proxyBeanMethods属性。

这个属性默认为true。他的意思就是,当从容器获取Bean时,是否用上面第1点中的代理对象调用方法获取bean。

增加验证如下:

	ConfigDemo bean = run.getBean(ConfigDemo.class);
    System.out.println(bean);
	// 如果@Configuration(proxyBeanMethods = true)代理对象调用方法
    User user = bean.user01();
    User user1 = bean.user01();
    System.out.println(user == user1);

当configration的proxyBeanMethods=true时,结果为true,否则结果为false。
也就是,当proxyBeanMethods=true,使用代理对象获取Bean,代理会拦截所有被@Bean修饰的方法,默认情况(bean为单例)下确保这些方法只被调用一次,放进容器,然后从容器查找到,就会直接使用,从而确保这些bean是同一个bean,即单例的。

否则,不使用代理对象获取Bean,每次获取都新建,所以两个Bean不相等。

这样做的主要目的是为了解决组件依赖问题,比如下面的部门被用户
依赖,可以保证用户依赖的部门是单实例。

验证代码如下:

首先让用户依赖部门

package com.example.ethan.config;
import com.example.ethan.bean.Dept;
import com.example.ethan.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods=true)  //告诉SpringBoot这是一个配置类 == 配置文件
public class ConfigDemo {
    @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
    public User user01(){
        User zhangsan = new User("zhangsan", 18);
        //user组件依赖了Dept组件
        zhangsan.setDept(rd());
        return zhangsan;
    }
    @Bean("my rd")
    public Dept rd(){
        return new Dept("研发部");
    }
}

然后测试用户依赖的组件是否是容器中的Bean

	User user01 = run.getBean("user01", User.class);
    Dept dept = run.getBean("tom", Dept.class);
    System.out.println("用户的宠物:"+(user01.getDept() == dept));
    // // 用户的部门:true

测试可以看到,当proxyBeanMethods=true时,结果为true,否则为false。

当proxyBeanMethods=true时也称为 Full模式,否则称为Lite模式。

Full(proxyBeanMethods = true)【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
组件依赖必须使用Full模式默认。其他默认是否Lite模式。
最佳实战

  • 配置 类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断
  • 配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式

到此这篇关于SpringBoot @Configuration与@Bean注解使用介绍的文章就介绍到这了,更多相关SpringBoot @Configuration与@Bean内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring中七种事务传播机制详解

    Spring中七种事务传播机制详解

    这篇文章主要介绍了Spring中七种事务传播机制详解,Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,Propagation枚举则引用了这些类型,开发过程中我们一般直接用Propagation枚举,需要的朋友可以参考下
    2024-01-01
  • Java安全之Mojarra JSF反序列化讲解

    Java安全之Mojarra JSF反序列化讲解

    JSF 和类似的 Web 技术之间的区别在于 JSF 使用 ViewStates(除了会话)来存储视图的当前状态(例如,当前应该显示视图的哪些部分),这篇文章主要介绍了Java安全之Mojarra JSF反序列化知识讲解,包括漏洞复现和漏洞分析,需要的朋友可以参考下
    2022-11-11
  • Java基础之自定义类加载器

    Java基础之自定义类加载器

    应该有很多小伙伴还不了解Java自定义类加载器吧,下文中有对Java自定义类加载器非常详细的描述,还有小伙伴们最喜欢的代码环节,需要的朋友可以参考下
    2021-05-05
  • spring boot-2.1.16整合swagger-2.9.2 含yml配置文件的代码详解

    spring boot-2.1.16整合swagger-2.9.2 含yml配置文件的代码详解

    这篇文章主要介绍了spring boot-2.1.16整合swagger-2.9.2 含yml配置文件,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • Springboot如何通过filter修改Header的值

    Springboot如何通过filter修改Header的值

    这篇文章主要介绍了Springboot如何通过filter修改Header的值问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Java 实现LZ78压缩算法的示例代码

    Java 实现LZ78压缩算法的示例代码

    这篇文章主要介绍了Java 实现LZ78压缩算法的示例代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-05-05
  • 超全MyBatis动态代理详解(绝对干货)

    超全MyBatis动态代理详解(绝对干货)

    这篇文章主要介绍了超全MyBatis动态代理详解(绝对干货),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • 关于SpringBoot中事务失效的几种情况

    关于SpringBoot中事务失效的几种情况

    这篇文章主要介绍了关于SpringBoot中事务失效的几种情况,Spring AOP默认使用动态代理,会给被代理的类生成一个代理类,事务相关的操作都通过代理来完成,使用内部方法调用时,使用的是实例调用,没有通过代理类调用方法,因此事务不会检测到失败,需要的朋友可以参考下
    2023-08-08
  • Java设计模式之状态模式

    Java设计模式之状态模式

    这篇文章介绍了Java设计模式之状态模式,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-10-10
  • Maven排除依赖和可选依赖的使用方法

    Maven排除依赖和可选依赖的使用方法

    我们知道Maven依赖具有传递性,例如A依赖于B,B依赖于C,在不考虑依赖范围等因素的情况下,Maven会根据依赖传递机制,将间接依赖C 引入到A中,但如果A出于某种原因,希望将间接依赖C排除,那该怎么办呢,Maven为用户提供了两种解决方式排出和可选
    2023-06-06

最新评论