spring的bean的加载方式

发布时间 2023-04-01 15:29:12作者: his365

1、配置文件+<bean/>标签

  • 配置文件
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"/>
  • 使用
public class App1 {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-bean.xml");
        DruidDataSource dataSource1 = (DruidDataSource)context.getBean("dataSource");
        DruidDataSource dataSource2 = (DruidDataSource)context.getBean(DruidDataSource.class);
        System.out.println(dataSource1);
        System.out.println(dataSource2);
    }
}

2、配置文件扫描+注解定义bean

  • 配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       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
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
">  
    <context:component-scan base-package="cn.tjhis.domain"/>
</beans>
  • 使用
@Component
public class Dog {
}

public class App2 {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-bean.xml");
        Dog bean = context.getBean(Dog.class);
        System.out.println(bean);
    }
}

3、注解方式声明配置类

@ComponentScan("cn.tjhis")
@Configuration
public class SpringConfig {
}

public class App3 {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        Dog bean = context.getBean(Dog.class);
        System.out.println(bean);
    }
}

4、使用@Import注解注入bean

  • 测试代码同3
@Import(Dog.class)
public class SpringConfig {
}

public class App4 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        Dog bean = context.getBean(Dog.class);
        System.out.println(bean);
    }
}

5、编程形式注册bean

  • SpringConfig 这个必须有,否则报错;
  • DogSpringConfig都不用添加任何注解
public class SpringConfig {
}

public class App5 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        // 上下文容器对象已经初始化完毕后,手工加载bean
        context.register(Dog.class);
        Dog bean = context.getBean(Dog.class);
        System.out.println(bean);
    }
}

6、导入实现了ImportSelector接口的类

public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata metadata) {
        boolean flag = metadata.hasAnnotation("org.springframework.context.annotation.Import");
        if(flag){
            return new String[]{"cn.tjhis.domain.Dog"};
        }
        return new String[]{"cn.tjhis.domain.Cat"};
    }
}

@Import(MyImportSelector.class)
public class SpringConfig {
}

public class App6 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        Dog bean = context.getBean(Dog.class);
        System.out.println(bean);
    }
}

7、导入实现了ImportBeanDefinitionRegistrar接口的类

  • 导入实现了ImportBeanDefinitionRegistrar接口的类,通过BeanDefinition的注册器注册实名bean,实现对容器中bean的裁定,例如对现有bean的覆盖,进而达成不修改源代码的情况下更换实现的效果
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        BeanDefinition beanDifinition = BeanDefinitionBuilder.rootBeanDefinition(Dog.class).getBeanDefinition();
        registry.registerBeanDefinition("dog",beanDifinition);
    }
}

@Import(MyImportBeanDefinitionRegistrar.class)
public class SpringConfig {
}

public class App7 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        Dog bean = context.getBean(Dog.class);
        System.out.println(bean);
    }
}

8、导入实现了BeanDefinitionRegistryPostProcessor接口的类

  • 导入实现了BeanDefinitionRegistryPostProcessor接口的类,通过BeanDefinition的注册器注册实名bean,实现对容器中bean的最终裁定
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        BeanDefinition beanDifinition = BeanDefinitionBuilder.rootBeanDefinition(Dog.class).getBeanDefinition();
        registry.registerBeanDefinition("dog",beanDifinition);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }
}

@Import(MyBeanDefinitionRegistryPostProcessor.class)
public class SpringConfig {
}

public class App2 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        Dog bean = context.getBean(Dog.class);
        System.out.println(bean);
    }
}