[Spring6.0源码解析]简述@Configuration注解

这篇具有很好参考价值的文章主要介绍了[Spring6.0源码解析]简述@Configuration注解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

@Configuration 标注在类上,启动 Spring 会自动扫描@Configuration注解的类,将其注册到IOC容器并实例化bean对象。如果在@Configuration注解的类中使用@Bean注解某个类对象的方法,Spring也会自动将注解了@Bean的方法注册到IOC容器,并进行实例化。

注解源码

@Configuration 注解本质上是个 @Component 注解,所以被 @Configuration 标注的类会被注册到IOC,且可以被 @ComponentScan 注解扫描到。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {

	/**
	 * 存入到Spring IOC容器中的ID
	 */
	@AliasFor(annotation = Component.class)
	String value() default "";

	/**
	 * 表示被@Configuration注解的类是否被代理,以及配置类中被@Bean注解的方法生成的Bean
     * 在IOC容器中是否为单例对象
     * 
     * true:full全局模式(默认)
     * false:lite轻量级模式
     * 
     * full全局模式,被@Configuration注解的配置类会被代理(CGLIB实现),配置类中被@Bean
     * 注解的方法生成的Bean在IOC容器中是单例模式。也就是说,无论调用多少次被@Bean标注的
     * 方法,返回的都是同一个bean对象。
     * 
     * lite轻量级模式,被@Configuration注解的配置类不会被代理,配置类中被@Bean注解的方法
     * 生成的Bean在IOC容器中也不是单例模式。也就是说,每次调用被@Bean注解标注的方法时,都会
     * 返回一个新的Bean对象。
     * 
	 * @since 5.2(Spring 5.2版本加入)
	 */
	boolean proxyBeanMethods() default true;

	/**
	 * 表示使用@Bean注解标注的方法是否需要唯一的方法名。
	 * 
	 * true:使用@Bean注解标注的方法具有唯一方法名称,且方法名称不会重叠
	 * false:使用@Bean注解标注的方法不唯一,存在重叠风险
	 * 
	 * 默认为true。
	 * 
	 * @since 6.0(Spring 6.0版本加入)
	 */
	boolean enforceUniqueMethods() default true;

}

使用场景

当某个类被@Configuration注解标注时,说明这个类是配置类。可以在这个类中,使用@Bean注解,向IOC容器中注入Bean对象;也可以使用 @Autowrite@Resource@Inject等注解来注入所需要的Bean对象。

另外,在使用 AnnotationConfigApplicationContext 类创建IOC容器事,需要注意两点:

  1. 如果使用传入 Class 入参的构造函数,则传入Class的配置类上的 @Configuration 可以省略,但是如果省略 @Configuration ,每次调用配置类中被 @Bean 标注的方法时,都会返回不同的 Bean 实例对象。
  2. 如果使用传入 String 入参的构造函数,表示传入应用程序的包名来创建 IOC容器,则配置类上的 @Configuration 不可以省略。

两种构造方法如下:

	/**
	 * Create a new AnnotationConfigApplicationContext, deriving bean definitions
	 * from the given component classes and automatically refreshing the context.
	 * @param componentClasses one or more component classes — for example,
	 * {@link Configuration @Configuration} classes
	 */
	public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		this();
		register(componentClasses);
		refresh();
	}

	/**
	 * Create a new AnnotationConfigApplicationContext, scanning for components
	 * in the given packages, registering bean definitions for those components,
	 * and automatically refreshing the context.
	 * @param basePackages the packages to scan for component classes
	 */
	public AnnotationConfigApplicationContext(String... basePackages) {
		this();
		scan(basePackages);
		refresh();
	}

使用案例

准备代码

  • 一个用于注册到IOC的类:
public class Person {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
  • 配置类
@Configuration
public class ConfigurationAnnotationConfig {
    @Bean
    public Person person(){
        return new Person();
    }
}
  • 启动类
public class ConfigurationAnnotationTest {
    private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationAnnotationTest.class);
    
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConfigurationAnnotationConfig.class);
        ConfigurationAnnotationConfig config = context.getBean(ConfigurationAnnotationConfig.class);
        Person person1 = config.person();
        Person person2 = config.person();
        LOGGER.info("person1 是否等于 person2 ===>> {}", (person1 == person2));
    }
}

proxyBeanMethods的使用

在之前提到,proxyBeanMethods配置表示用 @Bean 注解的方法在IOC容器中是否为单例对象,默认为true。

默认情况下,打印出结果如下:

person1 是否等于 person2 ===>> true

修改一下proxyBeanMethods的值为false:

@Configuration(proxyBeanMethods = false)
public class ConfigurationAnnotationConfig {
    @Bean
    public Person person(){
        return new Person();
    }
}

打印结果如下:

person1 是否等于 person2 ===>> false

从输出结果可以看出,当@Configuration中的proxyBeanMethods属性为false时,每次调用@Configuration注解标注类中被@Bean标注的方法时,都会返回不同的Bean实例对象。

创建IOC容器

传入配置类

调用AnnotationConfigApplicationContext类的构造方法传入配置类的Class对象创建IOC容器时,可以省略配置类上的@Configuration注解,如下:

public class ConfigurationAnnotationConfig {
    @Bean
    public Person person(){
        return new Person();
    }
}

输出结果:

person1 是否等于 person2 ===>> false

可以看到,若省略配置类上的@Configuration注解,则每次调用配置类中被@Bean注解标注的方法时,都会返回不同的Bean实例对象,与@Configuration中设置proxyBeanMethods的属性为false的效果相同。

传入包

调用AnnotationConfigApplicationContext类的构造方法传入包名创建IOC容器时,不能省略配置类上的@Configuration注解:

public class ConfigurationAnnotationConfig {
    @Bean
    public Person person(){
        return new Person();
    }
}

执行函数:

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("io.binghe.spring.annotation.chapter01.configuration");
        ConfigurationAnnotationConfig config = context.getBean(ConfigurationAnnotationConfig.class);
        Person person1 = config.person();
        Person person2 = config.person();
        LOGGER.info("person1 是否等于 person2 ===>> {}", (person1 == person2));
    }

此时运行main方法,会发生报错:

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'io.binghe.spring.annotation.chapter01.configuration.config.ConfigurationAnnotationConfig' available
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:331)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1148)
	at io.binghe.spring.annotation.chapter01.configuration.ConfigurationAnnotationTest.main(ConfigurationAnnotationTest.java:36)

添加上@Configuration注解则程序执行正常。

扩展知识

AnnotationConfigApplicationContext

Spring在 BeanFactory 的基础上提供一些具体容器的实现。AnnotationConfigApplicationContext就是一个用来管理注解 Bean 的容器。如下结构图:

从图中可以看到,AnnotationConfigApplicationContext继承GenericApplicationContext(通用应用上下文),而GenericApplicationContext又实现了BeanDefinitionRegistry接口,所以可以通过AnnotationConfigApplicationContext实例类注册BeanDefintion,然后调用refresh()方法来初始化上下文。AnnotationConfigApplicationContext还继承了AbstractApplicationContext,而AbstractApplicationContext提供了ApplicationContext的抽象实现文章来源地址https://www.toymoban.com/news/detail-410037.html

到了这里,关于[Spring6.0源码解析]简述@Configuration注解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring IOC @Configuration注解分析

    在使用SpringBoot开发时,最常用的注解有@Component、@Service、@Controller、@Configuration等。当类使用这些注解标记时,类会被Spring IOC容器管理,包括创建,填充属性和实例化。 但是Spring容器如何发现并将这些类放到容器进行管理呢? 今天这篇博客主要分析Spring如何处理@Configuratio

    2024年02月08日
    浏览(28)
  • Spring很常用的@Conditional注解的使用场景和源码解析

    你好,我是刘牌! 今天要分享的是Spring的注解@Conditional,@Conditional是一个条件注解,它的作用是判断Bean是否满足条件,如果满足条件,则将Bean注册进IOC中,如果不满足条件,则不进行注册,这个注解在SpringBoot中衍生出很多注解,比如 @ConditionalOnProperty , @ConditionalOnBean ,

    2023年04月14日
    浏览(32)
  • Spring6.0 源码部署

    Git JDK17 Gradle(版本号需要和Spring源码中的版本一致) 官网地址

    2024年02月16日
    浏览(38)
  • Spring6源码编译、安装

    名称 版本 jdk 17 gradle 8.1.1 spring源码版本 6.0.9 下载并解压 配置环境变量 验证 下载并解压 配置环境变量 验证 配置镜像仓库 spring在Github官网上有详细的说明文档,可以参考,但按照步骤做辉有些报错😅,还是按照自己总结的步骤来吧。 github源码地址 国内gitcode镜像 官方构建

    2024年02月08日
    浏览(31)
  • Spring5学习随笔-高级注解(@ComponentScan、@Configuration.....),替换XML配置文件

    学习视频:【孙哥说Spring5:从设计模式到基本应用到应用级底层分析,一次深入浅出的Spring全探索。学不会Spring?只因你未遇见孙哥】 Spring在3.x提供的新的注解,用于替换XML配置文件。 问题 : 配置Bean在应用的过程中替换了XML具体的什么内容? AnnotationConfigApplicationContext 配

    2024年02月05日
    浏览(36)
  • spring6.0.x源码调试环境搭建

    搭建一个spring源码调试环境,创建一个spring-demo模块,写一些测试代码。 给源码添加注释。 给源码打包 Spring Framework fork到自己的GitHub仓库,然后拉代码 下载 https://gradle.org/releases/ gradle/wrapper/gradle-wrapper.properties 找到版本为7.6的 gradle 找到 7.6 的版本,点击下载(注:点击之后

    2023年04月09日
    浏览(26)
  • spring复习:(50)@Configuration注解配置的singleton的bean是什么时候被创建出来并缓存到容器的?

    一、主类: 二、配置类: 三、singleton bean的创建流程 运行到context.refresh(); 进入refresh方法: 向下运行到红线位置时: 会实例化所有的singleton bean.进入finisheBeanFactoryInitialization方法: 向下拖动代码,可以看到beanFactory.preInstantiateSingletons(); 进入preInstantiateSingletons方法: 可以看

    2024年02月16日
    浏览(29)
  • 动力节点|Spring6框架学习教程,从基础到手撕源码一套打通

    Spring框架已广泛应用于诸多Java应用程序的开发中,它提供了很多解决方案及最佳实践,简化了Java应用程序的开发过程并加速了开发。 Spring6.0版本是下一个十年的新开端,动力节点老杜精心打造全新升级版Spring6教程,手把手教学,带大家从小白 蜕变 成为技术大牛 让 初学者

    2024年02月13日
    浏览(27)
  • 【Spring Boot】自动配置及重要注解解析

    1、springboot自动配置了哪些功能 1)tomcat的自动配置 引入了tomcat的相关依赖 2)自动配置springmvc及常用功能 我们在主启动类中加两行代码,查看一下spring boot加载了哪些组件 通过在控制台输出中搜索,我们可以发现转发请求的dispatcherServlet、解决乱码的characterEncodingFilter还有视

    2023年04月09日
    浏览(33)
  • 深入解析 Spring Framework 中 @Autowired 注解的实现原理

    关于@Autowired注解的作用 @Autowired 注解在Spring中的作用是实现依赖注入(Dependency Injection),它用于自动装配(autowiring)Spring Bean 的依赖关系。具体来说, @Autowired 注解有以下作用: 自动装配依赖 :通过在类的字段、构造函数、方法参数等地方使用 @Autowired 注解,Spring 容器会

    2024年02月08日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包