spring的bean

一、bean的八种加载方式

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

二、bean依赖的属性配置

  • 配置
cartoon:
  cat:
    name: tom
    age: 4
  mouse:
    name: jetty
    age: 3
  • 代码
@Data
public class Cat {
    private String name;
    private Integer age;
}

@Data
public class Mouse {
    private String name;
    private Integer age;
}

@Data
@ConfigurationProperties(prefix = "cartoon")
public class CartoonProperties {
    private Cat cat;
    private Mouse mouse;
}

/**
 * CartoonProp作为资源文件,去加载配置信息
 * EnableConfigurationProperties 注解:当 Cartoon 加载时,才去加载 CartoonProp,
 *                                    所以CartoonProp 没必要设置成bean
 *                                    Cartoon也没必要设置成bean,在app中用import引入  @Import(Cartoon.class)
 * @author Administrator
 */
@Data
@EnableConfigurationProperties(CartoonProp.class)
public class Cartoon {
    private Cat cat;
    private Mouse mouse;

    public Cartoon(CartoonProperties prop) {
        cat = new Cat();
        cat.setAge(prop.getCat() !=null && prop.getCat().getAge() != null ?prop.getCat().getAge():5 );
        cat.setName(prop.getCat() !=null && prop.getCat().getName() != null ?prop.getCat().getName():"大黑" );
        mouse = new Mouse();
        mouse.setAge(prop.getMouse() !=null && prop.getMouse().getAge() != null ?prop.getMouse().getAge():1 );
        mouse.setName(prop.getMouse() !=null && prop.getMouse().getName() != null ?prop.getMouse().getName():"小老鼠" );
    }

    public void play() {
        System.out.println("=========开始播放=========");
        System.out.println(StrUtil.format("{}岁的{}和{}岁的{}正在玩耍%n", cat.getAge(), cat.getName(), mouse.getAge(), mouse.getName()));
        System.out.println("=========结束播放=========");
    }
}

@SpringBootApplication
@Import(Cartoon.class)
public class AutobeanApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(AutobeanApplication.class, args);
        Cartoon cartoon = context.getBean(Cartoon.class);
        cartoon.play();
    }

}
posted @ 2023-04-01 15:23  his365  阅读(11)  评论(0编辑  收藏  举报