SpringBoot2底层注解@Configuration配置类

一、配置类

@Configuration这个注解作用就是告诉 springboot 这是一个配置类。

这个配置已经不陌生了,在之前 spring 相关的使用全注解方式时,就使用到了配置类。

在配置类里,可以使用@Bean标记在方法上,给容器注册组件,默认也是单实例的。

@Configuration //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {
    @Bean("user1") //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
    public User user01(){
        return new User("pingguo", 20);
    }
    @Bean("pet1")
    public Pet tomcatPet(){
        return new Pet("tomcat");
    }
}

主运行类还是之前示例中的,打印出所有组件的名称。

可以看到,有上面注册的 2 个组件:user1、pet1。

二、配置类本身也是组件

在主运行类的 main 方法里,加一个获取配置类的输出:

@SpringBootApplication(scanBasePackages = "com.pingguo")
public class MainApplication {
    public static void main(String[] args) {
        // 返回IOC容器
        final ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        // 查看容器里的组件
        final String[] beanDefinitionNames = run.getBeanDefinitionNames();
        for (String name: beanDefinitionNames) {
            System.out.println(name);
        }
        // 从容器中获取组件
        MyConfig bean = run.getBean(MyConfig.class);
        System.out.println("配置类也是组件:"   bean);
    }
}

运行 main 方法,

可以看到最后一个输出,说明配置类本身也是个组件。

三、proxyBeanMethods 属性

从springboot2.0之后,@Configuration 中多了一个属性 proxyBeanMethods,用来代理 bean 的。

默认值是true,也就是说该配置类会被代理(CGLIB),在同一个配置文件中调用其它被@Bean注解标注的方法获取对象时,springboot 总会检查容器中是否存在这个组件。

如果容器中存在,直接取。不存在的话,才会去创建,保证单实例。

现在看下false的情况。

@Configuration(proxyBeanMethods = false) //改成 false
public class MyConfig {
    @Bean("user1") //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
    public User user01(){
        return new User("pingguo", 20);
    }
    @Bean("pet1")
    public Pet tomcatPet(){
        return new Pet("tomcat");
    }
}

在主运行程序里多从调用方法获取对象,判断一下对象是否相等。

@SpringBootApplication(scanBasePackages = "com.pingguo")
public class MainApplication {
    public static void main(String[] args) {
        // 返回IOC容器
        final ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        // 查看容器里的组件
        final String[] beanDefinitionNames = run.getBeanDefinitionNames();
        for (String name: beanDefinitionNames) {
            System.out.println(name);
        }
        // 从容器中获取组件
        MyConfig bean = run.getBean(MyConfig.class);
        System.out.println("配置类也是组件:"   bean);
        User user1 = bean.user01();
        User user2 = bean.user01();
        System.out.println(user1 == user2);
    }
}

看最后的输出,会是 false。

这里引出 2 个名词:Full 全模式,Lite 轻量级模式。

  • Full (proxyBeanMethods = true) : 该模式下注入容器中的同一个组件无论被取出多少次都是同一个bean实例,即单实例对象,
  • 在该模式下 SpringBoot 每次启动都会判断检查容器中是否存在该组件。
  • Lite (proxyBeanMethods = false): 该模式下注入容器中的同一个组件无论被取出多少次都是不同的bean实例,即多实例对象,

在该模式下 SpringBoot 每次启动会跳过检查容器中是否存在该组件。

那么这个是用来解决什么场景的问题呢?答案:组件依赖。

有组件依赖的场景

看下2个实体类:User、Pet。

public class User {
    private String name;
    private Integer age;
    private Pet pet;
... ...

固定代码部分:有参构造、无参构造、get和set方法、toString方法,就省去了。

public class Pet {
    private String name;
... ...

修改下配置类里的方法:

@Configuration(proxyBeanMethods = true)
public class MyConfig {
    @Bean("user1") 
    public User user01(){
        User pingguo = new User("pingguo",20);
        pingguo.setPet(tomcatPet());
        return pingguo;
    }
    @Bean("pet1")
    public Pet tomcatPet(){
        return new Pet("tomcat");
    }
}

到main方法测试一下:

// 依赖关系
    User user01 = run.getBean("user1", User.class);
    Pet pet1 = run.getBean("pet1", Pet.class);
    System.out.println("依赖:"   (user01.getPet() == pet1));

这里就是判断当proxyBeanMethods = true的情况下,User对象的 pet,是不是容器中的 pet。

如果是,那么结果就是true。

此时再将proxyBeanMethods = false,重新运行一下,结果会是 false:

那么这 2 个模式分别在什么时候用呢?

当在你的同一个Configuration配置类中,注入到容器中的 bean 实例之间有依赖关系时,建议使用 Full 全模式。

当在你的同一个Configuration配置类中,注入到容器中的 bean 实例之间没有依赖关系时,建议使用 Lite 轻量级模式,以提高 springboot 的启动速度和性能。

以上就是SpringBoot2底层注解@Configuration配置类详解的详细内容,更多关于SpringBoot2注解@Configuration的资料请关注Devmax其它相关文章!

SpringBoot2底层注解@Configuration配置类详解的更多相关文章

  1. 一种angular的方法级的缓存注解(装饰器)

    本篇文章主要介绍了一种angular的方法级的缓存注解(装饰器),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Spring详细讲解@Autowired注解

    @Autowired注解可以用在类属性,构造函数,setter方法和函数参数上,该注解可以准确地控制bean在何处如何自动装配的过程。在默认情况下,该注解是类型驱动的注入

  3. 详解springboot测试类注解

    这篇文章主要介绍了springboot测试类注解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  4. @FeignClient注解中属性contextId的使用说明

    这篇文章主要介绍了@FeignClient注解中属性contextId的使用说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  5. SpringBoot整合Web之CORS支持与配置类和 XML配置及注册拦截器

    这篇文章主要介绍了SpringBoot整合Web开发中CORS支持与配置类和 XML配置及注册拦截器的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  6. Java泛型与注解全面分析讲解

    Java 泛型(generics)是 Jdk 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。Annotation(注解)是JDK1.5及以后版本引入的。它可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查。需要的可以参考一下

  7. Spring Boot 利用注解方式整合 MyBatis

    这篇文章主要介绍了Spring Boot 利用注解方式整合 MyBatis,文章围绕主主题的相关资料展开详细的内容介绍,需要的小伙伴可以参考一下

  8. SpringBoot底层注解超详细介绍

    这篇文章主要介绍了SpringBoot底层注解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

  9. Spring Boot自动配置的原理及@Conditional条件注解

    这篇文章主要介绍了Spring Boot自动配置的原理及@Conditional条件注解,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感兴趣的朋友可以参考一下

  10. Spring注解驱动之ApplicationListener用法解读

    这篇文章主要介绍了Spring注解驱动之ApplicationListener用法解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部