1、用的最多的一个注解搞定,最常用

  • @Component
  • @RestController
  • @Service

2、新建config类注入bean,此方式类似于以前的xml配置。

  • @Configuration标识这个类是配置类
  • @Bean标识这个方法返回的对象,和以前的xml中的bean一样

配置类

package com.example.config;

import com.example.dto.Teacher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfig {
    @Bean
    public Teacher getTeacher(){
        return new Teacher();
    }
}

Teacher类

package com.example.dto;

import lombok.Data;

@Data
public class Teacher {
    private int id;
    private String name;
    private int age;
}

3、Import注解导入,可以理解为嵌套,以前用xml的时候可以嵌套,注解也支持嵌套

  • 可以嵌套在启动类上
  • 可以嵌套在config类上

dog类

package com.example.dto;

import lombok.Data;

@Data
public class Dog {
    private int id;
    private String name;
    private int age;
}

引入dog类1

package com.example.config;

import com.example.dto.Dog;
import com.example.dto.Teacher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import(Dog.class)
public class MyConfig {
    @Bean
    public Teacher getTeacher(){
        return new Teacher();
    }
}

引入dog类2

package com.example;


import com.example.dto.Dog;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;

@SpringBootApplication
@MapperScan("com.example.dao")
@Import(Dog.class)
public class SpringbootMybatisApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootMybatisApplication.class, args);
    }

}

4、@Import + ImportSelector

  • 实现ImportSelector接口的selectImports方法
package com.example.config;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;

public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{"com.example.dto.Cat"};
    }
}

  • 配置类引入
@Configuration
@Import({Dog.class,MyImportSelector.class})

5、@Import + ImportBeanDefinitionRegistrar

  • 实现 ImportBeanDefinitionRegistrar 接口中的方法
package com.example.config;


import com.example.dto.Tree;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // 构建一个beanDefinition, 可以简单理解为bean的定义.
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Tree.class).getBeanDefinition();
        // 将beanDefinition注册到Ioc容器中.
        registry.registerBeanDefinition("tree", beanDefinition);
    }
}

  • 配置类引入
@Configuration
@Import({Dog.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})

6、@Import + DeferredImportSelector

  • DeferredImportSelector 它是 ImportSelector 的子接口
package com.example.config;

import com.example.dto.Apple;
import org.springframework.context.annotation.DeferredImportSelector;
import org.springframework.core.type.AnnotationMetadata;

public class MyDeferredImportSelector implements DeferredImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{Apple.class.getName()};
    }
}
  • 引入配置
@Configuration
@Import({Dog.class,MyImportSelector.class,MyDeferredImportSelector.class})

7、使用FactoryBean接口

FactoryBean接口和BeanFactory千万不要弄混了,从名字其实可以大概的区分开,FactoryBean, 后缀为bean,那么它其实就是一个bean, BeanFactory,顾名思义 bean工厂,它是IOC容器的顶级接口,这俩接口都很重要。

package com.example.config;

import com.example.dto.Bike;
import org.springframework.beans.factory.FactoryBean;

public class BikeFactoryBean implements FactoryBean<Bike> {
    @Override
    public Bike getObject() throws Exception {
        return new Bike();
    }

    @Override
    public Class<?> getObjectType() {
        return Bike.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

  • 引入这里没有引入Bike直接引入BikeFactoryBean
@Configuration
@Import({BikeFactoryBean.class,Dog.class,MyImportSelector.class})
public class MyConfig

8、使用 BeanDefinitionRegistryPostProcessor

其实这种方式也是利用到了 BeanDefinitionRegistry,在Spring容器启动的时候会执行 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 方法,大概意思就是等beanDefinition加载完毕之后,对beanDefinition进行后置处理,可以在此进行调整IOC容器中的beanDefinition,从而干扰到后面进行初始化bean。

package com.example.config;

import com.example.dto.Cup;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;

public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Cup.class).getBeanDefinition();
        registry.registerBeanDefinition("cup", beanDefinition);
    }

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

    }
}

  • 引入配置
@Configuration
@Import({MyBeanDefinitionRegistryPostProcessor.class})
public class MyConfig {

总结:
向spring容器中加入bean的几种方式(5大类8小类):

  • @Configuration + @Bean
  • @ComponentScan + @Component
  • @Import 配合接口进行导入
  • 使用FactoryBean。
  • 实现BeanDefinitionRegistryPostProcessor进行后置处理。

在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐