最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

Spring中Bean的加载方式~

来源:博客园


【资料图】

1、方式一:基于spring.xml方式配置Bean

user
import lombok.Data;/** * @author : ly */@Datapublic class User {    private String name;    private Integer age;}
xml
                        
test
/** * @author : ly */@SpringBootTestpublic 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.Useruser.name = 李四user.age = 20
test
@Testpublic 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
@Configurationpublic 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 */@Slf4jpublic 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
@Testpublic 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

关键词: 配置文件