SpringBoot
【黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)】
SpringBoot 原理篇
文章目录
- SpringBoot
- SpringBoot 原理篇
- 1 自动配置
- 1.11 bean 的加载控制【编程式】
- 1.11.1 bean 的加载控制
- 1.11.2 环境准备
- 1.11.3 加载控制
1 自动配置
1.11 bean 的加载控制【编程式】
1.11.1 bean 的加载控制
前面我们已经看完了8 种+ 的bean的加载方式【收获颇丰】,这些都可以往Spring 的容器中去加载bean
但是很多情况下,都需要根据情况去加载对应的bean,而不是每次都加载固定的那些bean【就是咱们可以对其进行控制】
bean的加载控制:bean的加载控制指根据特定情况对bean进行选择性加载以达到适用于项目的目标。
前面我们讲的各种方式中,哪些可以实现控制呢?
一、XML方式声明bean
二、XML+注解方式声明bean
二、使用@Component及其衍生注解@Controller 、@Service、@Repository定义bean;使用@Bean定义第三方bean,并将所在类定义为配置类或Bean
三、注解方式声明配置类
- 初始化实现FactoryBean接口的类,实现对bean加载到容器之前的批处理操作
- 加载配置类并加载配置文件(系统迁移)
- 使用proxyBeanMethods=true可以保障调用此方法得到的对象是从容器中获取的而不是重新创建的
四、使用@Import注解导入要注入的bean对应的字节码
- 使用@Import注解导入配置类
五、使用上下文对象在容器初始化完毕后注入bean
六、导入实现了ImportSelector接口的类,实现对导入源的编程式处理
七、导入实现了ImportBeanDefinitionRegistrar接口的类,通过BeanDefinition的注册器注册实名bean,实现对
容器中bean的裁定,例如对现有bean的覆盖,进而达成不修改源代码的情况下更换实现的效果
八、导入实现了BeanDefinitionRegistryPostProcessor接口的类,通过BeanDefinition的注册器注册实名bean,
实现对容器中bean的最终裁定
所以,通过下面的 四种加载方式,我们就可以通过编程的方式去控制bean 的加载。
1.11.2 环境准备
新建一个普通的Maven 工程模块
OK,直接创建
一个全新的Maven 工程
【添加坐标】
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.23</version>
</dependency>
</dependencies>
【创建类】
package com.dingjiaxiong.bean;
/**
* ClassName: Cat
* date: 2022/10/25 10:32
*
* @author DingJiaxiong
*/
public class Cat {
}
狗和老鼠同理
【配置类】
package com.dingjiaxiong.config;
/**
* ClassName: SpringConfig
* date: 2022/10/25 10:34
*
* @author DingJiaxiong
*/
public class SpringConfig {
}
【运行类】
package com.dingjiaxiong;
import com.dingjiaxiong.config.SpringConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* ClassName: App
* date: 2022/10/25 10:33
*
* @author DingJiaxiong
*/
public class App {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
String[] beans = ctx.getBeanDefinitionNames();
for (String bean : beans) {
System.out.println(bean);
}
}
}
直接运行,效果可以猜到了,几个长的,一个SpringConfig
OK,没问题
1.11.3 加载控制
先来个importselector 类
package com.dingjiaxiong.bean;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
/**
* ClassName: MyImportSelector
* date: 2022/10/25 10:38
*
* @author DingJiaxiong
*/
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.dingjiaxiong.bean.Cat"};
}
}
修改配置类
package com.dingjiaxiong.config;
import com.dingjiaxiong.bean.MyImportSelector;
import org.springframework.context.annotation.Import;
/**
* ClassName: SpringConfig
* date: 2022/10/25 10:34
*
* @author DingJiaxiong
*/
@Import(MyImportSelector.class)
public class SpringConfig {
}
OK,再次运行
OK, 上来了,给Cat 加个id名
package com.dingjiaxiong.bean;
import org.springframework.stereotype.Component;
/**
* ClassName: Cat
* date: 2022/10/25 10:32
*
* @author DingJiaxiong
*/
@Component("tom")
public class Cat {
}
再次运行
假设一个场景,如果我的环境中有Mouse,那我就加载Cat
package com.dingjiaxiong.bean;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
/**
* ClassName: MyImportSelector
* date: 2022/10/25 10:38
*
* @author DingJiaxiong
*/
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
try {
Class<?> clazz = Class.forName("com.dingjiaxiong.bean.Mouse");
if (clazz != null){ //说明加载上了老鼠
return new String[]{"com.dingjiaxiong.bean.Cat"}; //有老鼠就加载猫
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
直接运行
所以猫出来了
如果 现在有狼,猫就不要加载了
package com.dingjiaxiong.bean;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
/**
* ClassName: MyImportSelector
* date: 2022/10/25 10:38
*
* @author DingJiaxiong
*/
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
try {
Class<?> clazz = Class.forName("com.dingjiaxiong.bean.Wolf");
if (clazz != null){
return new String[]{"com.dingjiaxiong.bean.Cat"};
}
} catch (ClassNotFoundException e) {
// e.printStackTrace();
return new String[0];
}
return null;
}
}
可以看到这次就没有加载猫
又改成老鼠
这样又出来了,现在我们就可以根据自己的需要来控制某个bean 的加载与否了
回顾一下
根据任意条件确认是否加载bean