文章目录
- 3.4 @Import + DeferredImportSelector
- 4.使用FactoryBean接口
- 5.使用 BeanDefinitionRegistryPostProcessor
1.@Configuration + @Bean
@Configuration
public class MyConfiguration {
@Bean
public Person person() {
Person person = new Person();
person.setName("spring");
return person;
}
}
2.@Componet + @ComponentScan
@Component
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
@ComponentScan(basePackages = "com.springboot.*")
public class Demo1 {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class);
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
}
}
3.@Import注解导入
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
/**
* 用于导入一个class文件
* {@link Configuration @Configuration}, {@link ImportSelector},
* {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.
*/
Class<?>[] value();
}
3.1 @Import直接导入类
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
/**
* 直接使用@Import导入person类,然后尝试从applicationContext中取,成功拿到
**/
@Import(Person.class)
public class Demo1 {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class);
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
}
}
3.2 @Import + ImportSelector
@Import(MyImportSelector.class)
public class Demo1 {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class);
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
}
}
class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.springboot.pojo.Person"};
}
}
自定义了一个 MyImportSelector 实现了 ImportSelector 接口,重写selectImports 方法,然后将我们要导入的类的全限定名写在里面即可
3.3 @Import + ImportBeanDefinitionRegistrar
@Import(MyImportBeanDefinitionRegistrar.class)
public class Demo1 {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class);
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
}
}
class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 构建一个beanDefinition, 关于beanDefinition我后续会介绍,可以简单理解为bean的定义.
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Person.class).getBeanDefinition();
// 将beanDefinition注册到Ioc容器中.
registry.registerBeanDefinition("person", beanDefinition);
}
}
3.4 @Import + DeferredImportSelector
@Import(MyDeferredImportSelector.class)
public class Demo1 {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class);
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
}
}
class MyDeferredImportSelector implements DeferredImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
// 也是直接将Person的全限定名放进去
return new String[]{Person.class.getName()};
}
}
DeferredImportSelector 它是 ImportSelector 的子接口, 它和Spring Boot中的自动导入配置文件 延迟导入有关.
4.使用FactoryBean接口
FactoryBean 是一个Bean, BeanFactory 为ioc 工厂
@Configuration
public class Demo1 {
@Bean
public PersonFactoryBean personFactoryBean() {
return new PersonFactoryBean();
}
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class);
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
}
}
class PersonFactoryBean implements FactoryBean<Person> {
/**
* 直接new出来Person进行返回.
*/
@Override
public Person getObject() throws Exception {
return new Person();
}
/**
* 指定返回bean的类型.
*/
@Override
public Class<?> getObjectType() {
return Person.class;
}
}
5.使用 BeanDefinitionRegistryPostProcessor
这种方式也是利用到了 BeanDefinitionRegistry
, 在Spring容器启动的时候会执行 BeanDefinitionRegistryPostProcessor
的 postProcessBeanDefinitionRegistry
方法。
等beanDefinition
加载完毕之后, 对 beanDefinition
进行后置处理, 可以在此进行调整IOC容器中的beanDefinition
,从而干扰到后面进行初始化bean
。
public class Demo1 {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
MyBeanDefinitionRegistryPostProcessor beanDefinitionRegistryPostProcessor = new MyBeanDefinitionRegistryPostProcessor();
applicationContext.addBeanFactoryPostProcessor(beanDefinitionRegistryPostProcessor);
applicationContext.refresh();
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
}
}
class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Person.class).getBeanDefinition();
registry.registerBeanDefinition("person", beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}