Spring配置类之full和lite模式
本文基于Spring 5.2.7
Spring配置类不仅仅是@Configuration注解修饰的类,只是@Configuration修饰的类更加正式,Spring对此也是进行了区分处理,Spring将配置类划分为了full模式和lite模式。
一、配置类的full和lite模式
lite模式包含:
- 没有被@Configuration修饰,被@Component修饰
- 没有被@Configuration修饰,被@ComponentScan修饰
- 没有被@Configuration修饰,被@Import修饰
- 没有被@Configuration修饰,被@ImportResource修饰
- 没有任何Spring相关注解,类里面有@Bean修饰的方法
- 被@Configuration修饰,但是属性proxyBeanMethods = false
full模式包含:
- 被@Configuration修饰,且属性proxyBeanMethods = true(proxyBeanMethods 默认为true)
full模式使用特性:
- full模式下的配置类会被CGLIB代理生成代理类取代原始类型(在容器中)
- full模式下的@Bean方法不能是private和final
- 单例scope下不同@Bean方法可以互相引用,达到单实例的语义
lite模式使用特性:
- lite模式下的配置类不生成代理,原始类型进入容器
- lite模式下的@Bean方法可以是private和final
- 单例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模式相关推荐
- 521我发誓读完本文,再也不会担心Spring配置类问题了
生命太短暂,不要去做一些根本没有人想要的东西.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习 ...
- Spring(十三)- Spring 配置类的注解
文章目录 一.Spring 配置类的注解 1. @Configuration 2. @ComponentScan 3. @PropertySource 4. @Import 二.Spring 配置其他 ...
- 3、Spring配置类
从spring3.0开始,@Configuration用于定义配置类,用于取代xml文件,可以进行全注解开发 @Configuration类似xml中的<beans>标签 @bean类似x ...
- java spring配置类_spring 配置 Java配置类装配bean
https://www.cnblogs.com/chenbenbuyi/p/8457700.html 自动化装配的确有很大的便利性,但是却并不能适用在所有的应用场景,比如需要装配的组件类不是由自己的应 ...
- Spring的@Configuration配置类-Full和Lite模式
前言 各位小伙伴大家好,我是A哥.这是一篇"插队"进来的文章,源于我公众号下面的这句评论: 官方管这两种模式分别叫:Full @Configuration和lite @Bean m ...
- Spring框架学习笔记04:初探Spring——采用Java配置类管理Bean
文章目录 一.课程引入 二.采用Java配置类管理Bean (一)打开项目[SpringDemo2021] (二)创建net.hw.spring.lesson04包 (三)创建杀龙任务类 (四)创建勇 ...
- SSM框架笔记08:初探Spring——采用配置类与注解方式
初探Spring--采用配置类与注解方式 在上一讲的项目基础上继续. 不仅采用注解方式,而且用配置类替换Spring配置文件. 1.将xml_annotation包里的两个接口和四个类 ...
- spring源码分析06-spring配置类解析
什么是spring配置类? 类上有注解:@Configuration .@Component.@ComponentScan.@Import.@ImportResource 或者类中的任意方法有@Bea ...
- java配置ssm_不用xml 配置文件,纯粹使用java配置类搭建SSM项目
随着spring版本迭代更新,现在越来越倡导不使用复杂繁琐的配置文件来配置项目,下面介绍纯粹使用java 配置类来配置spring.springmvc.mybatis: 环境:java 8 + mav ...
最新文章
- ALV动态列Demo
- ThreadPoolExecutor线程池,shutdown和shutdownNow关闭线程池方式对比,以及确保线程池能够彻底关闭的一种方式
- Mysql SQL查询今天、昨天、n天内、第n天(执行效率不高)
- 光储充一体化充电站_福建全省首座光储充一体化公交充电站投入使用
- MySQL-locate()函数
- 上传一个 游戏server架构图
- c语言多线程_马云都称赞的C语言、C++学习路线!!!!
- linux分区文件 pe,关于linux的磁盘和分区的操作(一)
- myeclipse连接mysql生成数据表时中文字符乱码或问号(解决方法)
- 在CSS中clear属性的妙用
- 我竟然用git send-mail通过QQ邮箱提交了push request
- 什么是冷区热区_墙角装个小柜子 冷区立马变热区 有颜值还实用!
- animate.css在vue项目中的使用
- 汽车零配件行业MES系统,你了解多少?
- 卡西欧计算机做英语,卡西欧的这个小萌物 原来是台英语学习机
- HTML实现手机端适配
- 计算机在智能制造专业中的应用,数控技术在智能制造中的应用及发展分析
- 乐理入门: 二、时值、节奏、节拍
- matlab 死区,matlab中怎么产生死区
- bookmarks_2021_9_28