转自
https://www.cnblogs.com/init-qiancheng/p/14623522.html
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
@AliasFor(
annotation = Component.class
)
String value() default "";
boolean proxyBeanMethods() default true;
}
由该注解定义可知,该注解首先是一个组件,所以会被@SpringBootApplication注解扫描(扫描的前提是该注解必须在与启动类相同包或者子包中) 该注解中有一个属性 proxyBeanMethods,该属性的默认值是true,这个属性可以分为两种模式
- Full模式(即为默认值):proxyBeanMethods = true;
- Lite模式:proxyBeanMethods = false;
Full模式与Lite模式的区别
使用
Full模式
,这个配置类就被代理,就可以解决组件之间的依赖关系,他会先检查容器中是否存在组件的实例,如果存在就会直接使用,不存在才会进行创建;
如果是
Lite模式
,就不会产生代理类,每次调用都会执行一次,SpringBoot会跳过在容器中查找的步骤;
什么时候使用Full和Lite
当没有组件依赖的时候就是用Lite,这样会使程序启动更快;
当有组件依赖的时候就是用Full,即为默认值;
MyConfig.java
/**
* 1、配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
* 2、配置类本身也是组件
* 3、proxyBeanMethods:代理bean的方法
* Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
* Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
* 组件依赖必须使用Full模式默认。其他默认是否Lite模式
*/
@Configuration(proxyBeanMethods = false)//告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {
/**
* Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
*
* @return
*/
@Bean//给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
public People people() {
return new People(1, "迁承", dog());
}
@Bean
public Dog dog() {
return new Dog(1, "嘻嘻");
}
}
启动类
@SpringBootApplication
public class QianchengApplication {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(QianchengApplication.class, args);
/**
* 使用Full模式的时候会输出
* com.qiancheng.config.MyConfig$$EnhancerBySpringCGLIB$$fae131c9@27aae97b
* true
*/
/**
* 使用Late模式的时候输出
* com.qiancheng.config.MyConfig@13a37e2a
* false
*/
MyConfig bean = context.getBean(MyConfig.class);
System.out.println(bean);
People people = context.getBean("people", People.class);
Dog dog1 = context.getBean("dog", Dog.class);
System.out.println(people.getDog() == dog1);
}
}