一,概述
对于我们Java来说,创建对象无非就是new或者通过反射两种方式。
Spring中实例化对象一般是通过反射来实现的,但是Spring的强大之处不仅仅在于它为Java开发者提供了极大便利,更在于它的开放式架构,使得用户可以拥有最大扩展Spring的能力。
我们大致可以总结出以下五种实例化bean的方式:
1、 实现InstantiationAwareBeanPostProcessor接口;
2、 实现FactoryBean接口;
3、 通过Supplier接口;
4、 工厂方法factory-method;
5、 通过反射;
二,实现InstantiationAwareBeanPostProcessor接口
MyInstantiationAwareBeanPostProcessor.java
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanName.equals("a")) {
return new B();
}
return null;
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="a" class="com.bobo.A"></bean>
<bean class="com.bobo.MyInstantiationAwareBeanPostProcessor"></bean>
</beans>
测试代码:
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("boboTest.xml");
System.out.println(context.getBean("a"));
}
}
运行输出:
com.bobo.B@490ab905
三,实现FactoryBean接口
MyFactoryBean.java
@Component
public class MyFactoryBean implements FactoryBean<A> {
@Override
public A getObject() throws Exception {
return new A();
}
@Override
public Class<?> getObjectType() {
return A.class;
}
}
测试代码
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("boboTest.xml");
System.out.println(context.getBean("myFactoryBean"));
}
}
运行输出:
com.bobo.A@61230f6a
原理:请移步到这里查看:
四,通过Supplier接口
CreateSupplierB.java
public class CreateSupplierB {
public static B createB(){
return new B();
}
}
MyBeanFactoryPostProcessor.java
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("a");
GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition) beanDefinition;
genericBeanDefinition.setInstanceSupplier(CreateSupplierB::createB);
}
}
测试代码:
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("boboTest.xml");
System.out.println(context.getBean("a"));
}
}
运行输出:
com.bobo.B@cd3fee8
原理:请移步这里
Spring实例化(createBeanInstance)源码解析
五,工厂方法factory-method
1,静态工厂
MyStaticFactory.java
public class MyStaticFactory {
public static A getA() {
return new A();
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="a" class="com.bobo.MyStaticFactory" factory-method="getA"></bean>
</beans>
测试:
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("boboTest.xml");
System.out.println(context.getBean("a"));
}
}
运行输出:
com.bobo.A@5702b3b1
2,实例工厂
MyInstanceFactory.java
public class MyInstanceFactory {
public A getA() {
return new A();
}
}
aoolicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="myInstanceFactory" class="com.bobo.MyInstanceFactory"></bean>
<bean id="a" class="com.bobo.MyStaticFactory" factory-bean="myInstanceFactory" factory-method="getA"></bean>
</beans>
测试代码:
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("boboTest.xml");
System.out.println(context.getBean("a"));
}
}
运行输出:
com.bobo.A@5702b3b1
3,原理
请移步这里:
Spring实例化(createBeanInstance)源码解析
六,通过反射
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="a" class="com.bobo.A"></bean>
</beans>
测试代码:
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("boboTest.xml");
System.out.println(context.getBean("a"));
}
}
运行输出:
com.bobo.A@5bcab519