当前位置: 首页 > news >正文

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;}@Overridepublic 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 {@Overridepublic 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;}@Overridepublic 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 {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {// 获取person的Bean定义对象BeanDefinition personBeanDefinition = registry.getBeanDefinition("person");if (personBeanDefinition != null && personBeanDefinition instanceof GenericBeanDefinition) {// 往person的Bean定义对象中设置SupplierSupplier<Person> supplier = () -> {Person person = new Person();person.setAge(18);person.setName("BBB");return person;};((GenericBeanDefinition) personBeanDefinition).setInstanceSupplier(supplier);}}@Overridepublic 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实例对象@NullableT getObject() throws Exception;// Bean的类型@NullableClass<?> 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;}@Overridepublic 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> {@Overridepublic User getObject() throws Exception {return new User("001", "CCC");}@Overridepublic 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);}
}

http://www.lryc.cn/news/609502.html

相关文章:

  • 电脑忘记开机密码怎么办?【图文详解】5种方法重置/更改/取消/设置开机密码?
  • Java从入门到精通 - 算法、正则、异常
  • 深入浅出 RabbitMQ:简单队列实战指南
  • 【Linux指南】软件安装全解析:从源码到包管理器的进阶之路
  • 小杰数据结构(five day)——知人者智,自知者明。
  • WPF 按钮背景色渐变
  • 飞算 JavaAI:给需求分析装上 “智能大脑“
  • VPS云服务器Linux性能分析与瓶颈解决方案设计
  • 机器学习 决策树案例电信用户流失
  • 豆包新模型+PromptPilot深度评测:提示词工程的智能化突破
  • Chrontel 【CH7104B-BF】CH7104B HDMI to HDTV/VGA Converter
  • SJW-app-1
  • 力扣热题100——双指针
  • Android GPU测试
  • 豹女篇章-人形态技能加攻速
  • 数据离不开哈希
  • 【Linux | 网络】网络层(IP协议、NAT技术和ICMP协议)
  • 【前端:Html】--1.3.基础语法
  • 【人工智能99问】什么是Post-Training,包含哪些内容?(19/99)
  • 3.JVM,JRE和JDK的关系是什么
  • Linux 系统重置用户密码指南
  • 【09】C++实战篇——C++ 生成静态库.lib 及 C++调用lib,及实际项目中的使用技巧
  • vue3指定设置了dom元素的ref但是为null问题
  • 大模型 与 自驾 具身 3D世界模型等相关知识
  • 华为OD机考2025C卷 - 最小矩阵宽度(Java Python JS C++ C )
  • vim 组件 使用pysocket进行sock连接
  • 408数据结构排序部分知识的复盘:从原理到辨析的系统化梳理
  • 抗辐照DCDC与MCU在核环境监测设备中的集成应用
  • 远程测控终端RTU:工业物联的“神经末梢”与远程操控核心
  • CVPR论文解析:告别Janus问题,text-to-3D更一致!