Spring @Configuration配置类冷门知识之-Full和Lite模式

本文探讨了Spring @Configuration注解的Full和Lite模式的区别,通过代码示例展示了@Configuration如何影响类的实例化。当使用@Configuration时,类会被CGLIB代理,而@Component则不会。文章鼓励读者深入源码理解更多细节。

前言

此文介绍spring关于@Configuration的冷门知识(很少人知道,知道了其实也没多大的用处,本人理解的也很肤浅, 文章仅为介绍, 有兴趣的同学可以深入源码了解)

演示版本

jdk: 1.8

spring: 5.2.7.RELEASE

参考 :

spring中文文档: https://github.com/DocsHome/spring-docs/blob/master/SUMMARY.md

正文

本文默认大家都对spring有一定的了解, 基础知识就不太多介绍了, 直接讲@Configuration与其他注解(如 @Component,@Service...)的区别

spring官方管这两种模式分别叫:Full @Configuration和lite @Bean mode

中文手册介绍:

上述截图url: https://github.com/DocsHome/spring-docs/blob/master/pages/core/IoC-container.md#beans-java-basic-concepts

本次演示采用注解方式启动spring容器, xml也是可以的(xml个人很久没有配置了, 并不是很熟练), 用注解方式大家可以直接copy代码到搭好的spring或springboot项目中直接启动就可以了

直接上代码演示

A.java

public class A {
    public A (){ 
        System.out.println("A 被创建了..."); 
    } 
}

B.java

public class B { 
    public B (){ 
        System.out.println("B 被创建了..."); 
    } 
}

Test.java

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.stereotype.Component; 

@Component 
//@Configuration 
public class Test { 

    @Bean 
    public A a(){ 
        //当类上注解为@Component时idea可能会出现提示但不会阻止代码编译运行, idea还是很nice的 
        b(); 
        return new A(); 
    } 

    @Bean 
    public B b(){ 
        return new B(); 
    }
}

运行spring容器, 大家可以自行搭建, 我这个配置类啥也没干,只是做了一个@Configuration和配置包扫描路径, 确保我们的Test类能被spring扫描到

控制台输出 控制台B被创建了两次, 通过debug我们可以看到, Test是一个原生的类

接下来我们把Test的注解换成@Configuration 再试一下. 看看会不会有不同的效果

修改注解--运行

神奇的事发生了, Test类变成了CGLIB代理类, 机智的同学肯定也看了控制台, B只被创建了一次.

到这里我们已经简单了解了关于@Configuration与@Component之间的区别(当然还有更多的区别部分后面会分享到)

我们来深追一下spring源码吧!

源码相关类: org.springframework.context.annotation.ConfigurationClassUtils

org.springframework.context.annotation.ConfigurationClassUtils#checkConfigurationClassCandidate

当我们解析Test的时候(Test类上带了@Configuration注解),会给它的一个属性标识为Full,其他的标识为Lite

proxyBeanMethods 是@Configuration注解的一个属性, 默认值为true, 表示配置类是否需要被代理

 

然后在我们调用ConfigurationClassPostProcessor.postProcessBeanFactory()方法的时候会去判断我们的bean工厂当中是否有bean需要进行cglib代理。

对源码熟悉的同学可以应该可以找到入口, 找不到也可以通过截图打断点反推, 这里我画一下简单的执行流程到解析

个人理解, @Configuration就是为了让我们在编写业务代码的时候,将组件类型更细化区分

对于我们要引入完整的帮助类(),或者引入框架中的组件如 spring的后置处理器扩展, 监听器等等我们可以用@Component

而对于要解析外部依赖,注入bean和解析配置映射等关系时,我们可以用@Configuration标识该组件是配置类型的组件

相关总结-来源网络

// 当我们注册配置类的时候,可以不加Configuration注解,直接使用Component ComponentScan Import ImportResource注解,称之为Lite配置类

// 如果加了Configuration注解,就称之为Full配置类

// 如果我们注册了Lite配置类,我们getBean这个配置类,会发现它就是原本的那个配置类

// 如果我们注册了Full配置类,我们getBean这个配置类,会发现它已经不是原本那个配置类了,而是已经被cgilb代理的类了

// 如果配置类是Full配置类(即cgilb代理类),在类中@Bean只会被创建一次. 如两个@Bean相互调用, 只会创建一次

本文仅抛砖引玉, 更多用法和区别请参考 https://blog.csdn.net/demon7552003/article/details/107988310 (当然看其他相关的介绍也是可以的)

更过细节需要深入看源码, 本人对spring源码还只是入门阶段, 就不班门弄斧了.有兴趣的同学可以自己深入源码总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值