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);
    }

}
结果

image

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);
}
结果

image

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);
}
结果

image

@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);
    }
结果

image

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);
    }
结果

image

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);
    }
结果

image

总结:

Bean注入到Spring容器中大致可以分这么几种:

  • 配置文件
  • 注解声明
  • BeanDefinition
  • BeanFactoryPostProcessor注册Bean
  • FactoryBean
posted @   我也有梦想呀  阅读(51)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示