欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring实例化Bean的五种方式

程序员文章站 2022-05-24 20:49:57
...

一,概述

对于我们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"));
    }
}

运行输出:

[email protected]

三,实现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"));
    }
}

运行输出:

[email protected]

原理:请移步到这里查看:

Spring中FactoryBean真相揭秘

四,通过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"));
    }
}

运行输出:

[email protected]

原理:请移步这里

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"));
    }
}

运行输出:

[email protected]

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"));
    }
}

运行输出:

[email protected]

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"));
    }
}

运行输出:

[email protected]