用户登录
用户注册

分享至

Spring实例化Bean的五种方式

  • 作者: 武大地
  • 来源: 51数据库
  • 2021-09-28

一,概述

对于我们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.51sjk.com/Upload/Articles/1/0/288/288082_20210712003838607.jpg"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.51sjk.com/Upload/Articles/1/0/288/288082_20210712003838623.jpg"
       xsi:schemaLocation="http://www.51sjk.com/Upload/Articles/1/0/288/288082_20210712003838607.jpg http://www.51sjk.com/Upload/Articles/1/0/288/288082_20210712003838607.jpg/spring-beans.xsd http://www.51sjk.com/Upload/Articles/1/0/288/288082_20210712003838623.jpg 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

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

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

运行输出:

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.51sjk.com/Upload/Articles/1/0/288/288082_20210712003838607.jpg"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.51sjk.com/Upload/Articles/1/0/288/288082_20210712003838623.jpg"
       xsi:schemaLocation="http://www.51sjk.com/Upload/Articles/1/0/288/288082_20210712003838607.jpg http://www.51sjk.com/Upload/Articles/1/0/288/288082_20210712003838607.jpg/spring-beans.xsd http://www.51sjk.com/Upload/Articles/1/0/288/288082_20210712003838623.jpg 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.51sjk.com/Upload/Articles/1/0/288/288082_20210712003838607.jpg"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.51sjk.com/Upload/Articles/1/0/288/288082_20210712003838607.jpg http://www.51sjk.com/Upload/Articles/1/0/288/288082_20210712003838607.jpg/spring-beans.xsd http://www.51sjk.com/Upload/Articles/1/0/288/288082_20210712003838623.jpg 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.51sjk.com/Upload/Articles/1/0/288/288082_20210712003838607.jpg"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.51sjk.com/Upload/Articles/1/0/288/288082_20210712003838607.jpg http://www.51sjk.com/Upload/Articles/1/0/288/288082_20210712003838607.jpg/spring-beans.xsd http://www.51sjk.com/Upload/Articles/1/0/288/288082_20210712003838623.jpg 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
软件
前端设计
程序设计
Java相关