手动注册bean的两种方式:
实现ImportBeanDefinitionRegistrar
实现BeanDefinitionRegistryPostProcessor
1.实现ImportBeanDefinitionRegistrar
ImportBeanDefinitionRegistrar其本质也是通过BeanDefinitionRegistryPostProcessor来实现的。实现ImportBeanDefinitionRegistrar比较简单,也有多种方式,下面这个是最简单的手动注册bean的方式。
1.1 手动创建BeanDefinition
public class Foo {
public void foo() {
System.out.println("Foo.foo() invoked!");
}
}
public class FooImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinitionBuilder bdb = BeanDefinitionBuilder.genericBeanDefinition(Foo.class);
BeanDefinition bd = bdb.getBeanDefinition();
registry.registerBeanDefinition("foo", bd);
}
}
@SpringBootApplication
@Import(FooImportBeanDefinitionRegistrar.class)
public class Main implements CommandLineRunner {
@Autowired
private Foo foo;
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
@Override
public void run(String... args) throws Exception {
foo.foo();
}
}
Foo.foo() invoked!
1.2ClassPathBeanDefinitionScanner
public class FooImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry);
scanner.addIncludeFilter(new AssignableTypeFilter(Foo.class));
scanner.scan("com.study.bootwebsimple.register");//类和包必须都注入
}
}
1.3扫描自定义注解
一般都是扫描自定义的注解,才会继承ClassPathBeanDefinitionScanner)。这里你可以扫描自定义的注解,生成BeanDefinition(或其代理)的定义,然后注册到spring容器中。实现代码可以参考Mybatis的
org.mybatis.spring.annotation.MapperScannerRegistrar类,Mybatis扫描Mapper注解,通过MapperFactoryBean来代理了Mapper,并将其注册到spring中
2.实现BeanDefinitionRegistryPostProcessor
@Data
public class Person {
private String name;
public void foo() {
System.out.println("Person.foo() invoked!");
}
}
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(Person.class);
bdb.addPropertyValue("name", "lipo");
registry.registerBeanDefinition("person", bdb.getBeanDefinition());
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
@SpringBootApplication
@Import({FooImportBeanDefinitionRegistrar.class, MyBeanDefinitionRegistryPostProcessor.class})
public class Main implements CommandLineRunner {
@Autowired
private Foo foo;
@Autowired
private Person person;
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
@Override
public void run(String... args) throws Exception {
foo.foo();
person.foo();
}
}
Foo.foo() invoked!
Person.foo() invoked!