Spring之【Bean的实例化方式】

目录

方式一:InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation

源码分析

AbstractAutowireCapableBeanFactory中的createBean方法

AbstractAutowireCapableBeanFactory中的resolveBeforeInstantiation方法

AbstractAutowireCapableBeanFactory中的applyBeanPostProcessorsBeforeInstantiation方法

使用案例

方式二:Supplier

源码分析

AbstractAutowireCapableBeanFactory中的doCreateBean

AbstractAutowireCapableBeanFactory中的createBeanInstance方法

使用案例

方式三:FactoryMethod

源码分析

AbstractAutowireCapableBeanFactory中的doCreateBean

AbstractAutowireCapableBeanFactory中的createBeanInstance方法

使用案例

方式四:反射

源码分析

BeanUtils的instantiateClass方法

使用案例

方式五:FactoryBean

源码分析

FactoryBean接口

使用案例


方式一:InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation

源码分析

AbstractAutowireCapableBeanFactory中的createBean方法

Bean在实例化之前,会给个机会可以自定义创建Bean对象,如果自定义创建了Bean对象,就直接返回

AbstractAutowireCapableBeanFactory中的resolveBeforeInstantiation方法

执行Bean实例化之前的逻辑

AbstractAutowireCapableBeanFactory中的applyBeanPostProcessorsBeforeInstantiation方法

执行InstantiationAwareBeanPostProcessor的实例化之前方法回调

使用案例

  • 定义一个组件类
package spring.demo;

import org.springframework.stereotype.Component;

@Component
public class People {
    private Long no;
    private String name;

    public void setNo(Long no) {
        this.no = no;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "People{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
}
  • 自定义一个BeanPostProcessor并实现了InstantiationAwareBeanPostProcessor的实例化之前的方法
package spring.demo;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component;

import java.lang.reflect.Constructor;

@Component
public class CustomInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (beanClass == People.class) {
            try {
                // 这里自定义创建了Bean对象,并返回
                Constructor<?> constructor = beanClass.getDeclaredConstructor();
                People people = (People) constructor.newInstance();
                people.setNo(101L);
                people.setName("AAA");
                return people;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }
}
  • 定义扫包规则
package spring.demo;

import org.springframework.context.annotation.ComponentScan;

@ComponentScan("spring.demo")
public class SpringConfig {
}
  • 编写测试类并查看测试效果
package spring.demo;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
        People people = applicationContext.getBean(People.class);
        System.out.println(people);
    }
}

方式二:Supplier

源码分析

AbstractAutowireCapableBeanFactory中的doCreateBean

创建Bean实例对象

AbstractAutowireCapableBeanFactory中的createBeanInstance方法

从Bean定义对象中获取Supplier,并通过Supplier中get方法的逻辑中获取Bean实例对象

使用案例

  • 自定义一个组件类
package spring.demo;

import org.springframework.stereotype.Component;

@Component
public class Person {
    private int age;

    private String name;

    public void setAge(int age) {
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}
  • 自定义一个BeanDefinitionRegistryPostProcessor
package spring.demo;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.stereotype.Component;

import java.util.function.Supplier;

@Component
public class CustomBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        // 获取person的Bean定义对象
        BeanDefinition personBeanDefinition = registry.getBeanDefinition("person");
        if (personBeanDefinition != null && personBeanDefinition instanceof GenericBeanDefinition) {
            // 往person的Bean定义对象中设置Supplier
            Supplier<Person> supplier = () -> {
                Person person = new Person();
                person.setAge(18);
                person.setName("BBB");
                return person;
            };
            ((GenericBeanDefinition) personBeanDefinition).setInstanceSupplier(supplier);
        }
    }

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

    }
}
  • 编写测试类并查看测试效果
package spring.demo;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
        Person person = applicationContext.getBean(Person.class);
        System.out.println(person);
    }
}

方式三:FactoryMethod

源码分析

AbstractAutowireCapableBeanFactory中的doCreateBean

创建Bean实例对象

AbstractAutowireCapableBeanFactory中的createBeanInstance方法

通过工厂方法创建Bean实例对象

使用案例

  • 定义一个普通Java类
package spring.demo;

public class Toy {
}
  • 定义一个组件类
package spring.demo;

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class ToyFactory {

    @Bean(name = "toy")
    public Toy create() {
        return new Toy();
    }
}
  • 编写测试类并查看测试效果
package spring.demo;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
        Toy toy = applicationContext.getBean(Toy.class);
        System.out.println(toy);
    }
}

方式四:反射

源码分析

BeanUtils的instantiateClass方法

通过反射调用构造器实例化Bean对象

使用案例

  • 自定义组件类
package spring.demo;

import org.springframework.stereotype.Component;

@Component
public class Account {
    public Account() {
        System.out.println("执行Account构造器...");
    }
}
  • 编写测试类并查看测试效果
package spring.demo;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
        Account account = applicationContext.getBean(Account.class);
        System.out.println(account);
    }
}

方式五:FactoryBean

源码分析

FactoryBean接口

package org.springframework.beans.factory;

import org.springframework.lang.Nullable;

public interface FactoryBean<T> {

	String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";

    // 获取Bean实例对象
	@Nullable
	T getObject() throws Exception;

    // Bean的类型
	@Nullable
	Class<?> getObjectType();

    // 是否单例,默认是单例
	default boolean isSingleton() {
		return true;
	}
}

使用案例

  • 定义一个普通Java类
package spring.demo;

public class User {
    private String no;
    private String name;

    public User(String no, String name) {
        this.no = no;
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
}
  • 自定义一个FactoryBean
package spring.demo;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;

@Component
public class UserFactoryBean implements FactoryBean<User> {
    @Override
    public User getObject() throws Exception {
        return new User("001", "CCC");
    }

    @Override
    public Class<?> getObjectType() {
        return User.class;
    }
}
  • 编写测试类并查看测试效果
package spring.demo;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
        Object bean = applicationContext.getBean("userFactoryBean");
        System.out.println(bean);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值