本文基于Spring 5.2.7

Spring配置类不仅仅是@Configuration注解修饰的类,只是@Configuration修饰的类更加正式,Spring对此也是进行了区分处理,Spring将配置类划分为了full模式和lite模式。

一、配置类的full和lite模式

lite模式包含:

  1. 没有被@Configuration修饰,被@Component修饰
  2. 没有被@Configuration修饰,被@ComponentScan修饰
  3. 没有被@Configuration修饰,被@Import修饰
  4. 没有被@Configuration修饰,被@ImportResource修饰
  5. 没有任何Spring相关注解,类里面有@Bean修饰的方法
  6. 被@Configuration修饰,但是属性proxyBeanMethods = false

full模式包含:

  1. 被@Configuration修饰,且属性proxyBeanMethods = true(proxyBeanMethods 默认为true)

full模式使用特性:

  1. full模式下的配置类会被CGLIB代理生成代理类取代原始类型(在容器中)
  2. full模式下的@Bean方法不能是private和final
  3. 单例scope下不同@Bean方法可以互相引用,达到单实例的语义

lite模式使用特性:

  1. lite模式下的配置类不生成代理,原始类型进入容器
  2. lite模式下的@Bean方法可以是private和final
  3. 单例scope下不同@Bean方法引用时无法做到单例

lite测试用例

@Component
public class LiteConfig {@BeanUser u1() {return new User("小明", 13);}@BeanUser u2() {User localUser = u1();System.out.println(localUser.hashCode());User localUser2 = u1();System.out.println(localUser2.hashCode());return new User("小明2", 14);}public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(LiteConfig.class);Object liteConfig = ctx.getBean("liteConfig");System.out.println(liteConfig);}
}
368342628
1192923170
com.peace.test.configuration.test2.LiteConfig@59e2d8e3Process finished with exit code 0

full测试用例

@Configuration
public class FullConfig {@BeanUser u1() {return new User("小明", 13);}@BeanUser u2() {User localUser = u1();System.out.println(System.identityHashCode(localUser));User localUser2 = u1();System.out.println(System.identityHashCode(localUser2));return new User("小明2", 14);}public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(com.peace.test.configuration.test2.FullConfig.class);Object fullConfig = ctx.getBean("fullConfig");System.out.println(fullConfig);}}
1200906406
1200906406
com.peace.test.configuration.test2.FullConfig$$EnhancerBySpringCGLIB$$d004b363@4f0100a7

二、为何要区分full和lite模式

因为被Spring管理的类功能比较多,有一些是业务类,这些类解析起来比较简单和有规律,可归纳为lite模式一类,有一些类需要额外一些逻辑,需要生成CGLIB代理,所以这一类就被划分到full模式一类。

二、@Bean官方文档

@Bean注解始自Spring 3.0

Overview

表明一个方法,这个方法可以生产一个被Spring容器管理的bean。
这个注解的属性值和对应的语义都被特意的贴近Spring XML模式中的<bean>元素。
使用例子:

@Bean
public MyBean myBean() {// instantiate and configure MyBean objreturn obj;
}

Bean Names

当name属性可用时(难道还有不可用的时候?早期不可用,4.3.3才支持),确定bean name的默认策略是使用@Bean修饰的方法名。这是方便有易懂的,但如果需要显示命名,可以使用name(或者其属性别名)属性。同时注意,name属性接受一个Strings数组,允许一个单例bean有多个名字(也即一个主名字加一个或多个别名)。

@Bean({"b1", "b2"}) // bean available as 'b1' and 'b2', but not 'myBean'
public MyBean myBean() {// instantiate and configure MyBean objreturn obj;
}

Profile, Scope, Lazy, DependsOn, Primary, Order

注意,@Bean注解不提供profile,scope, lazy, depends-on和primary这些属性。相反,应该使用@Scope,@Lazy,@DependsOn,@Primary注解来表明这些语义。例如:

@Bean
@Profile("production")
@Scope("prototype")
public MyBean myBean() {// instantiate and configure MyBean objreturn obj;
}

上面提到的注解的语义和在类级别上使用时是一样的。
@Profile允许有环境选择性的注入某个bean
@Scope可以将bean的scope从singleton改到其他指定的scope
@Lazy只在默认的singleton scope下才起到实际效果
@DependsOn,在创建当前bean之前,除了创建当前bean直接引用的bean,@DependsOn会强制在创建当前bean之前创建其指定的bean,这通常在单例启动时有用。
@Primary是一种解决单个bean注入时有多个类型匹配的bean的歧义的机制。
此外,@Bean方法在注入时还可以使用qualifier注解和@Order注解,就像在bean上使用对应的注解一样,但是这种情况可能非常个性化(一个类有多个定义的场景)。Qualifiers在初始类型匹配后缩小了候选beans的范围。order值确定了多个collection注入场景时已解析元素的顺序(有多个目标bean类型匹配限定符也匹配场景)。
注意:@Order值可能影响注入点的优先级,但请知悉,他不会影响单例启动顺序,因为单例启动是顺序由依赖关系和@DependsOn的交叉关系决定的。另外,@Priority不能用在这里因为他不能在方法上声明,@Priority的语义可以通过@Order值结合@Primary实现。

@Bean Methods in @Configuration Classes

通常,@Bean方法被声明在@Configuration类里面。这种情况下,同一个类的里@Bean方法可能直接调用另一个@Bean方法,这确保了beans之间的引用强类型和导向的。这种所谓的inter-bean references是遵守scoping和AOP语义的保证,就像getBean()方法会查找引用一样。这些就是从最初的Spring JavaConfig中已知的语义,他需要在运行时为每个@Configuration类生成CGLIB子类,结果就是,这种模式下,@Configuration类和他的factory methods不能是final和private的,例如:

@Configuration
public class AppConfig {@Beanpublic FooService fooService() {return new FooService(fooRepository());}@Beanpublic FooRepository fooRepository() {return new JdbcFooRepository(dataSource());}// ...
}

@Bean Lite  Mode

@Bean方法也可以不在@Configuration类里面使用,例如,@Bean方法可以在@Component类里面甚至一个pojo类里面使用。这种场景下,@Bean方法会得到一个所谓的lite mode的处理。lite mode下的@Bean方法会被容器当作简单factory methods处理(类似于XML中factory-method的声明),并能正确被应用scoping和lifecycle回调。这种情形下,containing class保持不变,没有其他特殊的限制针对containing class和factory methods。
与@Configuration里@Bean方法语义不同,lite mode下inter-bean references不受支持。相反,lite mode下,当一个@Bean方法调用另一个@Bean方法,是标准的Java方法调用,Spring不会通过CGLIB拦截这个调用。这和Spring不拦截代理模式下内部@Transactional方法调用类似——Spring只在ASpectJ模式下拦截。使用例子:

@Component
public class Calculator {public int sum(int a, int b) {return a+b;}@Beanpublic MyBean myBean() {return new MyBean();}
}

Bootstrapping

查阅@Configuration文档获取更多使用AnnotationConfigApplicationContext等相关类启动容器的细节。

BeanFactoryPostProcessor returning @Bean methods

必须特别注意返回BeanFactoryPostProcessor(BFPP)类型的@Bean方法。因为BFPP对象必须在容器生命周期的很早阶段被实例化,在@Configuration里面他们能介入处理@Autowired,@Value,@PostConstruct注解,为了避免这种生命周期导致的问题,要将@Bean方法声明为static,使用例子:

@Bean
public static PropertySourcesPlaceholderConfigurer pspc() {// instantiate, configure and return pspc ...
}

通过标记这个方法为static,他能在其外部的@Configuration类还没实例化之前被调用,就能避免上面提到的生命周期冲突的问题。但是请注意,static @Bean方法不会得到scoping和AOP语义的增强。这在BFPP情形下是可行的,因为他们通常不被其他@Bean方法调用。作为提醒,任何非static @Bean方法返回BFPP类型时会有一条警告日志给出。

Spring配置类之full和lite模式相关推荐

  1. 521我发誓读完本文,再也不会担心Spring配置类问题了

    生命太短暂,不要去做一些根本没有人想要的东西.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习 ...

  2. Spring(十三)- Spring 配置类的注解

    文章目录 一.Spring 配置类的注解 1. @Configuration 2. @ComponentScan 3. @PropertySource 4. @Import 二.Spring 配置其他 ...

  3. 3、Spring配置类

    从spring3.0开始,@Configuration用于定义配置类,用于取代xml文件,可以进行全注解开发 @Configuration类似xml中的<beans>标签 @bean类似x ...

  4. java spring配置类_spring 配置 Java配置类装配bean

    https://www.cnblogs.com/chenbenbuyi/p/8457700.html 自动化装配的确有很大的便利性,但是却并不能适用在所有的应用场景,比如需要装配的组件类不是由自己的应 ...

  5. Spring的@Configuration配置类-Full和Lite模式

    前言 各位小伙伴大家好,我是A哥.这是一篇"插队"进来的文章,源于我公众号下面的这句评论: 官方管这两种模式分别叫:Full @Configuration和lite @Bean m ...

  6. Spring框架学习笔记04:初探Spring——采用Java配置类管理Bean

    文章目录 一.课程引入 二.采用Java配置类管理Bean (一)打开项目[SpringDemo2021] (二)创建net.hw.spring.lesson04包 (三)创建杀龙任务类 (四)创建勇 ...

  7. SSM框架笔记08:初探Spring——采用配置类与注解方式

      初探Spring--采用配置类与注解方式   在上一讲的项目基础上继续.   不仅采用注解方式,而且用配置类替换Spring配置文件.   1.将xml_annotation包里的两个接口和四个类 ...

  8. spring源码分析06-spring配置类解析

    什么是spring配置类? 类上有注解:@Configuration .@Component.@ComponentScan.@Import.@ImportResource 或者类中的任意方法有@Bea ...

  9. java配置ssm_不用xml 配置文件,纯粹使用java配置类搭建SSM项目

    随着spring版本迭代更新,现在越来越倡导不使用复杂繁琐的配置文件来配置项目,下面介绍纯粹使用java 配置类来配置spring.springmvc.mybatis: 环境:java 8 + mav ...

最新文章

  1. ALV动态列Demo
  2. ThreadPoolExecutor线程池,shutdown和shutdownNow关闭线程池方式对比,以及确保线程池能够彻底关闭的一种方式
  3. Mysql SQL查询今天、昨天、n天内、第n天(执行效率不高)
  4. 光储充一体化充电站_福建全省首座光储充一体化公交充电站投入使用
  5. MySQL-locate()函数
  6. 上传一个 游戏server架构图
  7. c语言多线程_马云都称赞的C语言、C++学习路线!!!!
  8. linux分区文件 pe,关于linux的磁盘和分区的操作(一)
  9. myeclipse连接mysql生成数据表时中文字符乱码或问号(解决方法)
  10. 在CSS中clear属性的妙用
  11. 我竟然用git send-mail通过QQ邮箱提交了push request
  12. 什么是冷区热区_墙角装个小柜子 冷区立马变热区 有颜值还实用!
  13. animate.css在vue项目中的使用
  14. 汽车零配件行业MES系统,你了解多少?
  15. 卡西欧计算机做英语,卡西欧的这个小萌物 原来是台英语学习机
  16. HTML实现手机端适配
  17. 计算机在智能制造专业中的应用,数控技术在智能制造中的应用及发展分析
  18. 乐理入门: 二、时值、节奏、节拍
  19. matlab 死区,matlab中怎么产生死区
  20. bookmarks_2021_9_28

热门文章

  1. linux0.11字符设备驱动及访问请求管理程序阅读注释笔记
  2. 九度oj 题目1114:神奇的口袋
  3. Python之PySerial串口通信
  4. B - 不容易系列之一
  5. 可以用jQuery代替$避免冲突
  6. 如何给 ESP32 选择外接 Flash 以及如何使能 QIO 模式
  7. silvaco器件仿真(一)-----宽禁带材料的雪崩击穿
  8. 小括号在c语言的作用,c语言小括号的用法有哪些用处.docx
  9. 美白,磨皮,搞笑图片处理
  10. 【前端】网页上动态显示超级可爱的萌妹子