Bean的加载方式与Bean加载控制

Bean的加载方式

两种基本加载方式

        加载Bean可以直接在xml中配置,也可以使用@Component、@Controller、@Service、@Service和@Configuration注解标记后在xml配置扫描的包自动将带有这些注解的类加载为Bean。

        @Configuration一般用来标记配置类,比@Component多一个proxyBeanMethods属性。proxyBeanMethods属性决定改配置类是否为代理对象,默认为true。使用代理对象的方法获取对象时,若容器中有者会返回容器中的对象。

        除去以上两种方式加载Bean,还有其它方式。主要列出以下6种方式。

@Componentscan

        新建一个配置类使用@Componentscan()注解,注解的参数为一个字符串数组,填写要扫描的包。@Componentscan()注解可以声明出扫描哪些包,这样下来就可以将xml完全代替。但是使用new ClassPathXmlApplicationContext("applicationContext.xml")来获取ioc容器只能传入xml文件,此时可以使用new AnnotationConfigApplicationContext(SpringConfig.class)来传入配置类。

        若使用new AnnotationConfigApplicationContext(SpringConfig.class)来传入配置类,则原本使用xml注册的Bean将失效。可以使用@ImportResource("applicationcontext.xml")注解声明要读取的xml配置文件。如果有相同id的Bean,后加载的覆盖先加载的。

@Import

        在配置类上还可以使用@Import()注解来配置Bean,参数需要填入某个类的class,可以是单个,也可以是一个数组。一个类上该注解只可以用一次,不可以多次使用。以该方式配置的Bean的名称为全路径名。以此形式加载的Bean若是配置类,即使配置类中没有@Configuration注解类中的@Bean也会生效

编码加载

        上下文容器初始化完之后,还可以手工加载Bean。AnnotationConfigApplicationContext类有一个registerBean()方法,传入要注册的Bean的名称、类型以及构造器的参数。以该方法加载的Bean后加载的会覆盖之前加载的。AnnotationConfigApplicationContext类还有一个register()方法,只需要传入一个类就可以加载该类的Bean。

实现Importselector接口

        创建一个类实现Importselector接口,重写其中的selectImports(AnnotationMetadata importingClassMetadata)方法,返回一个字符串,其中包含要加载的一些类的全类名。importingClassMetadata中存着元数据,可以用来加一些条件判断来判断已加载的Bean的状态,例如是否有某一个注解、注解中有什么参数等。可以通过已加载的Bean来判断是否加载一些类

public class MyImportselector implements Importselector{
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata){
        return new String[]{"com.itheima.bean.Dog","com.itheima.bean.cat"};
    }
}

ImportBeanDefinitionRegistrar

        创建一个类实现ImportBeanDefinitionRegistrar接口,可在重写的方法中创建Bean。主要是用到BeanDefinitionRegistry registry创建Bean对象。同一个Bean注册多次,后边的会覆盖前边的。

public class MyRegistrar implements ImportBeanDefinitionRegistrar{
    @override
    public void registerBeanDefinitions(AnnotationMetadata importingclassMetadata, BeanDefinitionRegistry registry){
        BeanDefinition beanDefinition = BeanDefinitionBuilder,rootBeanDefinition(Dog.class).getBeanDefinition();
        registry.registerBeanDefinition( beanName:"yellow",beanDefinition);
    }
}

BeanDefinitionRegistryPostProcessor

        创建一个类实现BeanDefinitionRegistryPostProcessor接口,重写其方法并且可以在其中注册Bean。与实现ImportBeanDefinitionRegistrar接口不同的是实现该接口的类所注册的Bean会在所有的实现ImportBeanDefinitionRegistrar接口的类注册完Bean完之后再注册,可以覆盖之前注册的Bean。若有多个实现BeanDefinitionRegistryPostProcessor接口的类则按加载这些类的顺序注册Bean。可以理解为Bean注册的后处理器

public class MyPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(BookServiceImpl4.class).getBeanDefinition();
        registry.registerBeanDefinition("bookService", beanDefinition);
    }
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    }
}

 

Bean加载控制

        上文后四种加载方式可以用来实现Bean加载控制,但是也有较为简便的注解可以实现Bean加载控制。

        使用注解实现还需要导坐标

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>2.5.4</version>
</dependency>

         注解有很多种,下边仅列出几种以供参考

根据类判断是否加载

@ConditionalOnClass(name ="全类名”)
@ConditionalOnMissingClass("全类名")

         前者可以传入一个类来判断,但是若类不存在将会报错。后者只可以传入字符串或字符串数组。不带Missing的是有才加载,带的是没有才加载

根据Bean加载

        根据是否有某个Bean加载

@conditional0nBean(name="jerry")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值