实现方式
在类上添加@Component
、@Service
、@Controller
、@Repository
等注解,配合@ComponentScan
扫描包路径。
适用场景
示例
@Service
public class UserService {
// 业务逻辑
}
实现方式
在配置类(@Configuration
标记的类)中,通过@Bean
标注方法,返回对象实例。
适用场景
示例
@Configuration
public class MyConfig {
@Bean
public User user() {
return new User("Marry", 12345L);
}
}
实现方式
在配置类中使用@Import
导入其他配置类
或普通类
,使其成为Bean。
适用场景
多个配置类
分散管理,根据需要组合
它们)@Component
示例
// 安全模块配置
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilter securityFilter() {
return new SecurityFilter();
}
}
// 数据访问模块配置
@Configuration
public class DataAccessConfig {
@Bean
public Repository repository() {
return new JpaRepository();
}
}
// 无特殊注解
public class BeanD {
}
// 主配置类
@Configuration
@Import({SecurityConfig.class, DataAccessConfig.class, BeanD.class})
public class ApplicationConfig {
@Bean
public MyService myService() {
// 可以使用DataAccessConfig中的bean
return new MyService(repository());
}
}
实现方式
需创建实现ImportSelector
接口的类,并重写selectImports()
方法返回需注册的类全限定名数组
。
适用场景
@EnableAutoConfiguration
通过AutoConfigurationImportSelector
加载spring.factories
中的自动配置类示例
AnnotationMetadata
参数可获取导入类的注解、接口、父类等信息
(如@EnableXXX的配置),用于更复杂的逻辑判断public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata metadata) {
System.out.println("元数据Class名称:" + metadata.getClassName());
//各种条件的判定,判定完毕后,决定是否装载指定的bean
boolean flag = metadata.hasAnnotation("org.springframework.context.annotation.Configuration");
if(flag){
return new String[]{"com.xc.springboot.bean.Dog"};
}
return new String[]{"com.xc.springboot.bean.Cat"};
}
}
// 使用方式
@Configuration
@Import(MyImportSelector.class)
public class MyConfig {
}
实现方式
需创建实现ImportBeanDefinitionRegistrar
接口的类,并重写registerBeanDefinitions()
方法通过BeanDefinitionRegistry动态注册Bean
。
适用场景
MyBatisMapper扫描
等,利用该机制动态生成代理类
示例
// 1.自定义注解@EnableMyFeature
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(MyFeatureRegistrar.class) // 关联注册实现类
public @interface EnableMyFeature {
String value() default "";
}
// 2.实现ImportBeanDefinitionRegistrar
public class MyFeatureRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware {
private Environment environment;
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
// 读取@EnableMyFeature注解的属性
Map<String, Object> attrs = metadata.getAnnotationAttributes(EnableMyFeature.class.getName());
String value = (String) attrs.get("value");
// 示例:根据环境变量决定是否注册Bean
boolean isEnabled = environment.getProperty("my.feature.enabled", Boolean.class, false);
if (isEnabled) {
BeanDefinition beanDef = BeanDefinitionBuilder
.genericBeanDefinition(MyServiceImpl.class)
.addPropertyReference("dependency", "myDependency")
.getBeanDefinition();
registry.registerBeanDefinition("myService", beanDef);
}
}
}
// 3.在配置类中使用@EnableMyFeature
@Configuration
@EnableMyFeature("customValue") // 触发MyFeatureRegistrar的执行
public class AppConfig {
// 其他Bean定义...
}
对比维度 | ImportSelector | ImportBeanDefinitionRegistrar |
---|---|---|
核心目的 | 动态返回需要导入的配置类全限定名 | 直接通过代码向容器注册Bean定义 |
使用场景 | 基于类的导入,适用于批量配置加载 | 基于Bean 定义的编程式注册,适用底层扩展,动态注册复杂Bean定义 |
执行时机 | 在配置类解析阶段执行 | 在 Bean 定义注册阶段执行 |
灵活性 | 通过间接导入类实现批量配置加载 | 直接操作 Bean 定义,支持更细粒度的控制(如属性注入、条件判断) |
依赖的输入参数 | 接收 AnnotationMetadata(当前 @Import 注解的元数据) | 接收 AnnotationMetadata 和 BeanDefinitionRegistry(可直接操作容器) |
与配置类的关系 | 依赖返回的配置类中的 @Bean 方法或 @Import 进一步注册 Bean | 不依赖配置类,直接注册 Bean 定义,甚至可注册非 @Configuration 类中的 Bean |
实现方式
实现FactoryBean
接口,重写getObject()
方法定义Bean实例,并通过@Component
或@Bean
注册接口实现类
适用场景
SqlSessionFactoryBean
)延迟
初始化或条件创建的Bean示例
getObject()
返回的对象,而非FactoryBean
本身@Component
public class DogFactoryBean implements FactoryBean<Dog> {
//创建bean的复杂过程
@Override
public Dog getObject() throws Exception {
Dog d = new Dog();
//.........
return d;
}
//bean的类型
@Override
public Class<?> getObjectType() {
return Dog.class;
}
//bean是否单例
@Override
public boolean isSingleton() {
return true;
}
}
实现方式
通过ApplicationContext
或BeanFactory
直接注册Bean。
适用场景
示例
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args)
.getBeanFactory()
.registerSingleton("customBean", new CustomBean());
}
}
实现方式
通过META-INF/spring.factories
声明自动配置类,结合@Conditional
实现按需装配。
适用场景
示例
# META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.xc.MyAutoConfiguration
@Configuration
public class MyAutoConfiguration {
@Bean
public MyBean myBean() { ... }
}
实现方式
在XML文件中通过<bean>
标签定义Bean,并在配置类中使用@ImportResource
导入XML文件。
适用场景
示例
<!-- beans.xml -->
<bean id="xmlUser" class="com.example.User" />
@ImportResource("classpath:beans.xml")
@Configuration
public class XmlConfig { ... }
实现方式
实现BeanDefinitionRegistryPostProcessor
接口,在postProcessBeanDefinitionRegistry()
方法中手动注册BeanDefinition
。
适用场景
动态注册Bean
(如Spring Boot Starter自动配置)示例
Bean实例化前
修改容器元信息@Component
public class DynamicRegistrar implements BeanDefinitionRegistryPostProcessor {
// 注册Bean定义(先执行)
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
BeanDefinition definition = BeanDefinitionBuilder
.genericBeanDefinition(User.class)
.addPropertyValue("name", "DynamicUser")
.getBeanDefinition();
registry.registerBeanDefinition("dynamicUser", definition);
}
// 修改Bean定义(后执行-加载所有Bean定义之后、Bean实例化之前)
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 在这里可以对 BeanFactory 进行进一步的配置
System.out.println("Bean factory post-processing");
}
}