Spring中Bean的加载方式~
1、方式一:基于spring.xml方式配置Bean
user
import lombok.Data;
/**
* @author : ly
*/
@Data
public class User {
private String name;
private Integer age;
}
xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user1" class="com.ly.domain.User">
<property name="name" value="张三"/>
<property name="age" value="25"/>
</bean>
</beans>
test
/**
* @author : ly
*/
@SpringBootTest
public class GetBeanTest {
private ApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
@Test
public void testXML(){
User user1 = app.getBean("user1", User.class);
System.out.println("user1 = " + user1);
}
}
结果
2、方式二:基于properties方式配置Bean
properties
user.(class) = com.ly.domain.User
user.name = 李四
user.age = 20
test
@Test
public void testProperties(){
GenericApplicationContext applicationContext = new GenericApplicationContext();
//创建一个PropertiesBeanDefinitionReader,可以从properties读取Bean的信息,将读到的Bean信息放到applicationContext中
PropertiesBeanDefinitionReader propReader = new PropertiesBeanDefinitionReader(applicationContext);
//创建一个properties文件对应的Resource对象
Resource classPathResource = new ClassPathResource("bean1.properties");
//加载配置文件
propReader.loadBeanDefinitions(classPathResource);
applicationContext.refresh();
User user = applicationContext.getBean(User.class);
System.out.println(user);
}
结果
3、方式三:@Component + @ComponentScan,衍生注解@Controller、@Service、@Repository...
这种方式常用,而且不叫简单就不写案例了
4、方式四:@Bean针对第三方的Bean
例如我们配置MybatisPlus分页插件时,就是使用@Bean方式把分页插件MybatisPlusInterceptor交给Spring管理
@Bean
@Configuration
public class MybatisPlusConfig {
//分页拦截器
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
paginationInterceptor.setMaxLimit(500L);
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setDbType(DbType.MYSQL);
interceptor.addInnerInterceptor(paginationInterceptor);//分页
return interceptor;
}
}
5、方式五:@Import|@ImportSelector|@ImportBeanDefinitionRegistrar导入对应的Bean
@Import
通过import的方式将bean加入到spring容器中,这些在容器中bean名称是该类的全类名 ,比如com.ly.User
test
@Import(User.class)
@ImportSelector
UserImportSelector
/**
* @author : ly
*/
@Slf4j
public class UserImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
log.info("通过ImportSelector导入对应的Bean");
return new String[]{"com.ly.domain.Dog"};
}
}
MyImportSelector
/**
* @author : ly
*/
@Import(UserImportSelector.class)
public class MyImportSelector {
}
test
@Test
public void testImportSelector(){
Dog dog = ctx.getBean(Dog.class);
System.out.println("dog = " + dog);
}
结果
@ImportBeanDefinitionRegistrar
UserImportBeanDefinitionRegistrar
public class UserImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
registry.registerBeanDefinition("dogRegister",new RootBeanDefinition(Dog.class));
}
}
UserImportRegisterAnnotation
/**
* @author : ly
*/
@Import(UserImportBeanDefinitionRegistrar.class)
public class UserImportRegisterAnnotation {
}
test
@Test
public void testImportRegister(){
Dog dog = ctx.getBean("dogRegister", Dog.class);
System.out.println("dog = " + dog);
}
结果
6、方式六:BeanFactoryPostProcessor注册对应的Bean
UserBeanDefinitionRegistryPostProcessor
/**
* @author : ly
*/
public class UserBeanDefinitionRegistryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
User user = new User();
user.setName("王五");
user.setAge(20);
configurableListableBeanFactory.registerSingleton("userProcessor", user);
}
}
测试
@Test
public void testProcessor(){
AnnotationConfigApplicationContext app2 = new AnnotationConfigApplicationContext();
app2.register(UserBeanDefinitionRegistryPostProcessor.class);
app2.refresh();
User userProcessor = app2.getBean("userProcessor", User.class);
System.out.println("userProcessor = " + userProcessor);
}
结果
7、方式七:FactoryBean
当我们通过配置文件、注解声明或者是注册BeanDenifition的方式,往Spring容器中注入了一个class类型为FactoryBean类型的Bean时候,其实真正注入的Bean类型为getObjectType方法返回的类型,并且Bean的对象是通过getObject方法返回的。
UserFactoryBean
/**
* @author : ly
*/
public class UserFactoryBean implements FactoryBean {
@Override
public Object getObject() throws Exception {
User user = new User();
user.setName("赵六");
user.setAge(23);
return user;
}
@Override
public Class<?> getObjectType() {
return User.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
test
@Test
public void testFactorBean(){
app2.register(UserFactoryBean.class);
app2.refresh();
User bean = app2.getBean(User.class);
System.out.println("bean = " + bean);
}
结果
总结:
Bean注入到Spring容器中大致可以分这么几种:
- 配置文件
- 注解声明
- BeanDefinition
- BeanFactoryPostProcessor注册Bean
- FactoryBean
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构