文章目录
1、@Configuration配置类
@Configuration(proxyBeanMethods = true)
- 默认true,表示被@Bean标识的方法都会被cglib进行代理,会走bean生命周期的行为,如@postConstruct
- 在同一个configuration中调用@Bean标识的方法,无论调用几次都是同一个bean,这个bean只创建一次
@Configuration(proxyBeanMethods = false)
- false表示被@Bean标识的方法都不会被cglib进行代理,不会走bean生命周期的行为
- 在同一个configuration中调用@Bean标识的方法,就只是普通方法的执行而已,并不会从容器中获取对象,调用多次,创建多个对象
组件类
//用户类
public class User {
private Pet pet;
public User(Pet pet) {
this.pet = pet;
}
public Pet getPet() {
return pet;
}
@PostConstruct
public void init() {
System.out.println("user 初始化。。。");
}
}
//宠物类
public class Pet {
@PostConstruct
public void init() {
System.out.println("pet 初始化。。。");
}
}
配置类
@Configuration(proxyBeanMethods = true)
public class MyConfig {
@Bean
public User user(){
Pet pet = pet();
Pet pet1 = pet();
return new User(pet);
}
@Bean
public Pet pet(){
return new Pet();
}
}
启动类
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
//获取ioc容器
ConfigurableApplicationContext context =
SpringApplication.run(SpringbootApplication.class, args);
//获取组件
User user1 = context.getBean("user", User.class);
User user2 = context.getBean("user", User.class);
Pet pet1 = context.getBean("pet", Pet.class);
Pet pet2 = context.getBean("pet", Pet.class);
System.out.println(user1==user2);
System.out.println(pet1==pet2);
System.out.println(user1.getPet()==pet1);
}
}
当proxyBeanMethods =true
- 在同一个Configuration中pet和pet1对象实例为同一个
- pet进行了一次初始化
- 容器中多次获取组件都是同一个对象实例
当proxyBeanMethods =false
- 在同一个Configuration中pet和pet1为不同的对象实例( idea也会警告飘红)
- pet没有走bean的初始化方法,只是简单调用new 新对象
- Configuration中获取实例非单例,但是ioc容器中依然是单例
- user中的pet是在configration中获取的对象,pet1也是从configration中获取的,分别创建了两个对象
所以,如果配置类中的@Bean标识的方法之间不存在依赖调用的话,可以设置为false,可以避免拦截方法进行代理操作,也是提升性能的一种优化。但是需要注意,@Bean标识的返回值对象还是会放入到容器中的,从容器中获取bean还是可以是单例的,会走生命周期。
2、@Scope设置组件作用域
- prototype:多例,ioc容器启动并不会去调用方法创建对象放在容器中。每次获取的时候才会调用方法创建对象。
- singleton:单例(默认值),ioc容器启动会调用方法创建对象方到容器中。每次获取就是直接从容器中拿。
- request:同一次请求创建一个实例
- session:同一个session创建一个实例
@Configuration
@ComponentScan("spring.module.annotation")
public class MainConfig {
@Bean
@Scope(value = "prototype")
public Person person(){
return new Person(1,"张三");
}
}
2、@Lazy懒加载
- 单例bean:默认ioc容器启动的时候创建对象
- 懒加载bean:ioc容器启动不创建对象。第一次使用(获取)bean时候创建对象,只创建一次
@Configuration
@ComponentScan("spring.module.annotation")
public class MainConfig {
@Bean
@Lazy
public Person person(){
return new Person(1,"张三");
}
}
3、@Conditional按照条件加载bean
- 注释在方法:windows系统加载李雷,linux系统加载韩梅梅
- 注释在类上:满足条件整个类才会配置加载bean
@Configuration
@ComponentScan("spring.module.annotation")
public class MainConfig {
@Conditional({WindowsCondition.class})
@Bean("lilei")
public Person person01(){
return new Person(10,"李雷");
}
@Conditional({LinuxCondition.class})
@Bean("hanmeimei")
public Person person02(){
return new Person(20,"韩梅梅");
}
}
加载条件
//判断是否linux系统
public class LinuxCondition implements Condition {
/**
*ConditionContext:判断条件能使用的上下文
*AnnotatedTypeMetadata:注释信息
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//1、获取ioc使用的beanFactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//2.获取类加载器
ClassLoader classLoader = context.getClassLoader();
//3.获取当前环境信息
Environment environment = context.getEnvironment();
//4.获取bean定义的注册类(注册、移除、获取查看等)
BeanDefinitionRegistry registry = context.getRegistry();
//linux返回true,否则返回false
String property = environment.getProperty("os.name");
return property.contains("linux") ? true : false;
}
}
//判断是否windows系统
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//linux返回true,否则返回false
String property = context.getEnvironment().getProperty("os.name");
return property.contains("Windows") ? true : false;
}
}
4、@Import为容器添加组件
- 传统方式:包扫描+组件标注注解(@Controller等)
- @Bean:导入第三方包里面的组件
1)@Import
容器中自动注册组件,id默认全类名
@Configuration
@ComponentScan("spring.module.annotation")
@Import({Red.class, Blue.class})
public class MainConfig {
}
打印ioc容器中所有组件
public class Client {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
for (String beanName : context.getBeanDefinitionNames()) {
System.out.println(beanName);
}
}
}
结果:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
spring.module.annotation.entity.Red
spring.module.annotation.entity.Blue
2)@ImprotSelector
返回多个组件的全类名数组
@Configuration
@ComponentScan("spring.module.annotation")
@Import({MyImportSelector.class})
public class MainConfig {
}
自定义逻辑返回需要导入的组件
public class MyImportSelector implements ImportSelector {
/**
* 返回值:导入容器的组件数组,id为全类名
*AnnotationMetadata:标注此注解的类上面的所有注解信息
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"spring.module.annotation.entity.Black", "spring.module.annotation.entity.Yellow"};
}
}
三个注解信息分别为:@Configuration、@ComponentScan、@Import
结果:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
spring.module.annotation.entity.Black
spring.module.annotation.entity.Yellow
3)@ImprotBeanDefinitionRegistrar
手动注册bean到容器中
@Configuration
@ComponentScan("spring.module.annotation")
@Import({MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
public class MainConfig {
}
自定义手工注册
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* AnnotationMetadata:此注解类的所有注解信息
* BeanDefinitionRegistry:BeanDefinition注册类
* 通过BeanDefinitionRegistry.registerBeanDefinition手工注册bean
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean exist = registry.containsBeanDefinition("spring.module.annotation.entity.Black");
//如果存在Black的bean,则会注册White的bean
if(exist){
//指定bean名
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(White.class);
registry.registerBeanDefinition("white",rootBeanDefinition);
}
}
}
结果:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
spring.module.annotation.entity.Black
spring.module.annotation.entity.Yellow
white
5、@Value赋值
- 基本数值
- 可以写#{};如#{5-2}
- 可以写${};取出配置文件properties中的值
6、@PropertySource加载外部配置文件
@PropertySource(value={"classpath:/jdbc.properties"})
@Configuration
public class MyConfig(){
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/148663.html